분류 전체보기 (83)
아우라지 삼산점

인천에 있는 아우라지에 방문했습니다.

예전에 한번 갔던 집인데 맛이 괜찮아서 다시 한번 갔습니다.



뭐 이렇다네요


들어가서 카운터쪽에서 안을 본 사진입니다.

자리는 꽤 넓은데 주말이라 그런지 사람들이 많네요.


메뉴

 

 

메뉴판입니다.  성인 4명(남2, 여2) 참게빠가메기매운탕 대자를 주문했습니다.

참게랑 빠가사리, 메기가 들어갑니다.



라면사리, 수제비 반죽입니다.  가서 그냥 가져오시면 됩니다.

나중에 가져오기 귀찮으니 미리 세팅을..


참게빠가메기매운탕

요리가 나왔습니다.  참게는 1인당 반개씩 4개가 나오네요.

팔팔팔 끓여줍니다.


위처럼 보글보글 끓기 시작하면 야채를 먼저 건져 먹습니다.

빠가사리와 메기도 있는데 사진이 없다니...

국물은 기름져보이는데 맛은 의외로 깔끔합니다.

매운 매운탕을 생각하시고 오시면 실망하실수도 있습니다. 

안 칼칼하다고 맛이 없는건 아닙니다.


건더기를 사악 건져먹고 국물이 남으면..


수제비와 라면을 넣어줍니다..


그리고 짠 완성되면~ 짭니다~

물을 좀 넣어서 먹으면 괜찮습니다.


총평

깔끔하게 떨어지는 국물 맛이 좋습니다.  깍두기 맛있는데 사진이 없네요.

아무튼 엄청 칼칼하게 매운 매운탕이 아닙니다.

칼칼하진 않지만 국물맛이 좋아서 무난하게 맛있게 느껴집니다.

재방문의사 O


위치


이 장소를 Daum지도에서 확인해보세요.
인천 부평구 삼산동 427-4 | 아우라지 삼산점
도움말 Daum 지도

'맛집' 카테고리의 다른 글

합정 라멘집 길라멘  (0) 2018.05.04
상수 라멘트럭  (0) 2016.10.10
아우라지 삼산점  (0) 2016.10.07
더 파스텔라(THE PASTELA!)  (0) 2016.09.18
명동교자  (1) 2016.09.12
  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트(Spring boot)에서 mybatis(oracle) 적용하기

2016/09/19 - [개발/JAVA] - 스프링 부트(Spring boot)에서 logback 적용하기


이어서.. 스프링 부트에서 마이바티스를 연동해 보도록 하겠습니다.

실무에서 주로 사용되는 mapper xml을 이용한 방법을 살펴보겠습니다.

DB는 오라클을 사용하지만 드라이버만 바꾸면 다른 종류의 DB도 사용이 가능합니다.


pom.xml

오라클 드라이버는 메이븐 중앙 저장소에 없기 때문에 오라클 저장소를 추가해 줍니다.

parent와 동일 레벨로 저장소를 추가합니다.


<repositories>

        <repository>

            <id>oracle</id>

            <name>ORACLE JDBC Repository</name>

            <url>http://maven.jahia.org/maven2</url>

        </repository>

    </repositories>

그리고 오라클 드라이버와 mybatis spring goot starter 종속성을 추가해줍니다.

마이바티스에서 스프링 대응하여 나온 것으로 기존 마이바티스는 필요없습니다.

(http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure)

<dependency>

        <groupId>org.mybatis.spring.boot</groupId>

        <artifactId>mybatis-spring-boot-starter</artifactId>

        <version>1.1.1</version>

    </dependency>

         

    <dependency>

        <groupId>com.oracle</groupId>

        <artifactId>ojdbc6</artifactId>

        <version>11.1.0.7.0</version>

    </dependency>


application.yml

spring.datasource 설정 부분이 추가되었으며, mybatis 설정 부분이 추가되었습니다.

mybatis-config.xml형식으로 설정을 하고 싶으면 mybatis.config-location설정을 쓰시면 됩니다.

다양한 설정 항목들이 있으니 스프링, 마이바티스 문서를 참고해 주세요.

datasource항목은 대부분 개발과 상용이 다를테니 샘플보다는 프로파일별로 옮겨서 관리를 하시는게 좋습니다.

spring:
  profiles: 
    active: dev
  timerName: exampleTimer
  datasource:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    url: jdbc:oracle:thin:@111.222.111.222:1521:SIDHERE
    username: donnert
    password: password
---
mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  configuration:
    lazyLoadingEnabled=true
    aggressiveLazyLoading=false
    mapUnderscoreToCamelCase=true
---
spring:
  profiles: local
  task:
    fixedDelay: 1000
    name: localTask
---
spring:
  profiles: dev
  task:
    fixedDelay: 5000
    name: devTask

Application.java

기존에 사용하시던대로 MapperScan어노케이션으로 매퍼 패키지 위치를 정의해 줍니다.

package net.donnert.spring.boot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@MapperScan("net.donnert.spring.boot")
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

TestMapper.java

쿼리 xml과의 인터페이스를 제공해줍니다.

package net.donnert.spring.boot;

public interface TestMapper {
	public String getValueFromDatabase();
}


testMapper.xml

src/main/resources하위에 mapper폴더 생성 후 testMapper.xml을 생성해 줍니다.

내용은 위에서 정의한 인터페이스 쿼리를 작성해줍니다.




    

Timer.java

매퍼 빈을 주입 받아서 그냥 호출하면 됩니다.

package net.donnert.spring.boot;

import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
public class Timer {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	private AtomicInteger loopCounter = new AtomicInteger();
	
	@Autowired
	private StopWatch watch;
	
	@Autowired
	private TestMapper testMapper;
	
	@Value("${spring.task.name}")
	private String taskNamePrefix;
	
	@Value("${spring.timerName}")
	private String timerName;
	
	@PostConstruct
	public void init() {
		logger.info("{} init", timerName);
		watch.start();
	}

	@Scheduled(fixedDelayString = "${spring.task.fixedDelay}")
	public void tick() throws InterruptedException{
		watch.stop();
		logger.info(testMapper.getValueFromDatabase());
		String taskName = taskNamePrefix + "-" + String.valueOf(loopCounter.getAndIncrement());
		watch.start(taskName);
	}

	@Bean
	public StopWatch watch() {
		return new StopWatch();
	}
}

테스트

실행해 보면 아래처럼 쿼리 로그와 결과가 정상적으로 찍히는 모습을 볼 수 있습니다.

2016-09-20 13:56:08.904  INFO(12012)[main] [net.donnert.spring.boot.Timer:33] exampleTimer init
2016-09-20 13:56:09.286  INFO(12012)[main] [o.s.j.e.a.AnnotationMBeanExporter:431] Registering beans for JMX exposure on startup
2016-09-20 13:56:09.349  INFO(12012)[main] [o.s.s.a.ScheduledAnnotationBeanPostProcessor:244] No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2016-09-20 13:56:09.372  INFO(12012)[main] [n.d.spring.boot.Application:57] Started Application in 3.229 seconds (JVM running for 3.793)
2016-09-20 13:56:10.812 DEBUG(12012)[pool-2-thread-1] [n.d.s.b.T.getValueFromDatabase:145] ==>  Preparing:  SELECT NAME FROM TEST WHERE ROWNUM=1
2016-09-20 13:56:10.902 DEBUG(12012)[pool-2-thread-1] [n.d.s.b.T.getValueFromDatabase:145] ==> Parameters: 
2016-09-20 13:56:10.930 DEBUG(12012)[pool-2-thread-1] [n.d.s.b.T.getValueFromDatabase:145] <==      Total: 1
2016-09-20 13:56:10.932  INFO(12012)[pool-2-thread-1] [net.donnert.spring.boot.Timer:40] 테스트이름

간단한 예제같지만 프로파일, 로깅, DB연결 등 필요한 부분들은 모두 들어가 있기 떄문에 실무에서도 

배치나 데몬 프로세스로 충분히 사용하실 수 있습니다.

스프링 부트를 이용하면 복잡한 설정도 필요없고

이미 구현된 것들을 설정만 해서 쓰는 방식이기 때문에 개발 시간이 많이 단축됩니다.


완성소스

https://github.com/donnert/spring-boot/tree/master/spring-boot-batch


  Comments,   0  Trackbacks
  • 크로노
    정말 정말 감사합니다^^
    계속 해맷는데 이제야 되는 소스를 찾았네요^^
  • jepark3452
    pom.xml에 오라클 추가시 에러나시는분들은

    <!-- dependencies 태그 위쪽에 추가 하세요.-->
    <repositories>
    <repository>
    <id>oracle</id>
    <name>ORACLE JDBC Repository</name>
    <url>https://maven.atlassian.com/3rdparty/</url>
    </repository>
    </repositories>

    <!-- dependencies 태그 안쪽에 추가하세요. -->
    <dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>12.1.0.1-atlassian-hosted</version>
    </dependency>


    참고하세요~

    ※ 참고 : https://github.com/regenea8/GroupWare/blob/master/GroupWare/pom.xml
댓글 쓰기
스프링 부트(Spring boot)에서 logback 적용하기

2016/09/08 - [개발/JAVA] - 스프링 부트(Spring boot)에서 프로퍼티 사용하기


전에 이어서 이번에는 logback을 적용시켜보겠습니다.

사실 이미 스프링 부트가 알아서 다 적용시켜놨지면 설정파일을 이용해서

프로파일 적용 및 파일에 쓰는 방법을 해보겠습니다.


logback.xml --> logback-spring.xml로 만드세요

src/main/resources 폴더에 logback.xml을 작성합니다.

아래 샘플은 제가 사용하고 있는 파일입니다.

<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="1 minutes">

<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

<property value="/temp/log/log" name="LOG_FILE_PREFIX"/>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">

<encoder>

<charset>UTF-8</charset>

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p}\(${PID:- }\)[%t] [%logger{30}:%line] %msg%n</pattern>

</encoder>

</appender>

<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE">

<encoder>

<charset>UTF-8</charset>

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p}\(${PID:- }\)[%t] [%logger{30}:%line] %msg%n</pattern>

</encoder>

<file>${LOG_FILE_PREFIX}.log</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<fileNamePattern>${LOG_FILE_PREFIX}_%d{yyyyMMdd}.log</fileNamePattern>

</rollingPolicy>

</appender>


<springProfile name="local">

<logger name="net.donnert.spring.boot" level="DEBUG" />

<root level="INFO">

<appender-ref ref="CONSOLE"/>

</root>

</springProfile>


<springProfile name="!local">

<logger name="net.donnert.spring.boot" level="DEBUG" />


<root level="INFO">

<appender-ref ref="CONSOLE"/>

<appender-ref ref="FILE"/>

</root>

</springProfile>

</configuration>


테스트

springprofile노드를 이용해 현재 적용중인 프로파일 별 설정이 가능합니다.

xml을 보시면 현재 프로파일이 local인 경우는 CONSOLE appender를 이용, 콘솔에만 출력

local이 아닌 경우 CONSOLE, FILE appender를 이용 파일에도 출력을 하게 됩니다.


아래처럼 로깅 패턴이 정의된 형식으로 바뀌었으며 프로파일을 dev(local이 아닌 프로파일)로 바꾸게 되면 추가적으로 D:\temp\log\log.log파일이 생성되는 것을 보실 수 있습니다.


2016-09-19 11:03:28.664  INFO(10952)[main] [net.donnert.spring.boot.Timer:30] exampleTimer init

2016-09-19 11:03:28.833  INFO(10952)[main] [o.s.j.e.a.AnnotationMBeanExporter:431] Registering beans for JMX exposure on startup

2016-09-19 11:03:28.846  INFO(10952)[main] [o.s.s.a.ScheduledAnnotationBeanPostProcessor:244] No TaskScheduler/ScheduledExecutorService bean found for scheduled processing

2016-09-19 11:03:28.857  INFO(10952)[pool-2-thread-1] [net.donnert.spring.boot.Timer:37] StopWatch '': running time (millis) = 189



2016/09/23 - [개발/JAVA] - 스프링 부트(Spring boot)에서 mybatis(oracle) 적용하기



  Comments,   0  Trackbacks
  • qnrtjd123
    혹시 보시게 되면 에러확인좀 부탁드려요

    Failed to auto configure default logger context
    Reported exception:
    ch.qos.logback.core.joran.spi.JoranException: Problem parsing XML document. See previously reported errors.
    at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:65)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:141)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:103)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:53)
    at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)
    at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:150)
    at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
    at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
    at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
    at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:273)
    at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:189)
    at com.board.BoardApplication.main(BoardApplication.java:12)
    Caused by: org.xml.sax.SAXParseException; lineNumber: 53; columnNumber: 1; 예기치 않은 파일의 끝입니다.
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1239)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:648)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:332)
    at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:59)
    ... 16 more
    14:33:58,963 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
    14:33:58,963 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
    14:33:58,963 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/D:/springBoot/workspace/board/target/classes/logback.xml]
    14:33:59,019 |-ERROR in ch.qos.logback.core.joran.event.SaxEventRecorder@21300751 - XML_PARSING - Parsing fatal error on line 53 and column 1
    14:33:59,019 |-ERROR in ch.qos.logback.core.joran.event.SaxEventRecorder@21300751 - org.xml.sax.SAXParseException; lineNumber: 53; columnNumber: 1; 예기치 않은 파일의 끝입니다.




    • 첫줄에
      <?xml version="1.0" encoding="UTF-8"?>
      가 빠진것 같습니다. 본문 수정했으니 적용해보세요
    • jepark3452
      <?xml version="1.0" encoding="UTF-8"?>

      <configuration scan="true" scanperiod="1 minutes">
      <include resource="org/springframework/boot/logging/logback/defaults.xml" />
      <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
      <!-- 변수 지정 : 로그저장 경로는 자신의 환경에 맞게 수정해야 함. -->
      <property value="C:/spring-tool-suite-3.8.4/workspace/spring.boot/logs/schedule-log" name="LOG_FILE_PREFIX" />
      <!-- <property value="/temp/log/log" name="LOG_FILE_PREFIX" /> -->

      <!-- FILE Appender -->
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${LOG_FILE_PREFIX}.log</file>
      <!-- 일자별로 로그파일 적용하기 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_FILE_PREFIX}_%d{yyyyMMdd}.log</fileNamePattern>
      <maxHistory>60</maxHistory> <!-- 일자별 백업파일의 보관기간 -->
      </rollingPolicy>
      <encoder>
      <charset>UTF-8</charset>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p}\(${PID:- }\)[%t] [%logger{30}:%line] %msg%n</pattern>
      </encoder>
      </appender>

      <!-- CONSOLE Appender -->
      <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
      <charset>UTF-8</charset>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p}\(${PID:- }\)[%t] [%logger{30}:%line] %msg%n</pattern>
      </encoder>
      <!-- <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern>
      </layout> -->
      </appender>

      <!-- TRACE > DEBUG > INFO > WARN > ERROR, 대소문자 구분 안함 -->
      <!-- profile 을 읽어서 appender 을 설정할수 있다.(phase별 파일을 안만들어도 되는 좋은 기능) -->
      <springProfile name="local">
      <root level="INFO">
      <appender-ref ref="CONSOLE" />
      </root>
      </springProfile>
      <springProfile name="!local">
      <root level="INFO">
      <appender-ref ref="FILE" />
      <appender-ref ref="CONSOLE" />
      </root>
      </springProfile>
      </configuration>
    • jepark3452
      저도 에러가 나서 여기저기서 검색끝에 해결했습니다. 위에 댓글 확인해 보세요~
    • 어랏 감사합니다
      코드 하이라이터 제거과정에서 뭔가 어긋난거 같네요
댓글 쓰기
더 파스텔라(THE PASTELA!)

합정에 생긴 지 얼마 안된 파스타집을 가봤습니다.

합정역 7번 출구에서 도보로 멀지 않은 곳에 있습니다.


밖에서 보는 식당의 모습과 입간판


실내 모습입니다.  저녁 시간이라 사람이 많네요.

내부는 그리 크지 않습니다.


메뉴가 꽤 많습니다.  예전에 먹어본 명란젓 크림파스타는 맛이 꽤 괜찮았었습니다.

이번엔 그냥 기본 까르보나라와 느끼한 맛을 잡아 줄 해산물 리조또를 주문했습니다.


식전빵과 피클입니다.  식전빵은 그냥저냥 부드럽고 따뜻한 식빵 느낌입니다.

부담없이 가볍고 좋습니다.  피클은 강하지 않은 그냥 피클.


식전빵 먹으면서 바라본 주방의 모습.


까르보나라

베이컨이 들어간 기본 까르보나라입니다.

생각보다 후추가 강해서 전혀 느끼하지 않습니다.

적당히 느끼하지 않으면서  맛있게 잘 들어갑니다. 


해산물 리조또

첫 인상은 매콤한 맛이 강하게 느껴집니다.

매콤하면서 녹아있는  치즈 맛이 적당히 어우러집니다.


안에는 통통한 새우와 보이지 않지만 해산물들이 의외로 많이 들어있습니다.

이 요리 역시 후추맛이 느껴지면서 적당히 맵고 느끼합니다.



총평

아담한 분위기와 저렴한 가격에 맛있는 요리를 먹을 수 있는 집입니다.

두 요리 다 후추가 많이 느껴졌으나 오히려 느끼하지 않게 잘 넘어갑니다.

들리는 소문에는 봉골레 파스타가 맛있다고 합니다.  먹어보진 못했지만...

그냥 까르보나라보다는 명란 버전을 추천

재방문 의사 O


위치

이 장소를 Daum지도에서 확인해보세요.
서울 마포구 합정동 366-7 1층 | 더파스텔라
도움말 Daum 지도

'맛집' 카테고리의 다른 글

합정 라멘집 길라멘  (0) 2018.05.04
상수 라멘트럭  (0) 2016.10.10
아우라지 삼산점  (0) 2016.10.07
더 파스텔라(THE PASTELA!)  (0) 2016.09.18
명동교자  (1) 2016.09.12
  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트(Spring boot)에서 profile, yml 사용하기


2016/09/08 - [개발/JAVA] - 스프링 부트(Spring boot)에서 프로퍼티 사용하기

이전 글에 이어서...

이번에는 프로파일별로 프로퍼티를 설정 해 볼 예정입니다.

개발을 하다보면 로컬->개발기->상용기 형식으로 바뀌면서 설정값들이 바뀌어야 하는 경우가 많습니다.

개발할때는 로그를 1초마다 찍고 싶고 개발기에서는 5초마다 찍고 싶을때 주석을 풀고 지우고 하지 말고 아래처럼 프로파일로 관리를 하면 됩니다.

yaml형식의 파일을 사용하며 하나의 파일 안에서 프로파일 별로 설정값들이 설정됩니다.


application.properties

더 이상 사용하지 않습니다.  지워주세요.


application.yml

이제 모든 설정은 이 yml파일 안에서 하게 됩니다.

yml파일은 탭문자가 들어가면 안되며, 아래와 같이 구분은 ---으로 하게 됩니다.


첫번째 섹션은 현재 어떤 프로파일로 동작을 할건지를 선언해주고 있습니다.

(application.properties 파일의 spring.profiles.active=local과 동일합니다)

또한 프로파일에 구분없이 사용할 값들도 정의되어있습니다.


그 다음 local 프로파일이 적용 되었을 경우 사용할 설정값과 

dev 프로파일이 적용되었을 경우 사용할 설정 값이 ---로 구분되어서 선언되어 있습니다.


spring:

  profiles: 

    active: local

  timerName: exampleTimer


---

spring:

  profiles: local

  task:

    fixedDelay: 1000

    name: localTask


---

spring:

  profiles: dev

  task:

    fixedDelay: 5000

    name: devTask


Timer.java

프로파일과 상관없이 돌아가는 timeName속성을 찍는 로그를 추가해 줍니다.

package net.donnert.spring.boot;

import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
public class Timer {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	private AtomicInteger loopCounter = new AtomicInteger();
	
	@Autowired
	private StopWatch watch;
	
	@Value("${spring.task.name}")
	private String taskNamePrefix;
	
	@Value("${spring.timerName}")
	private String timerName;
	
	@PostConstruct
	public void init() {
		logger.info("{} init", timerName);
		watch.start();
	}

	@Scheduled(fixedDelayString = "${spring.task.fixedDelay}")
	public void tick() throws InterruptedException{
		watch.stop();
		logger.info(watch.prettyPrint());
		String taskName = taskNamePrefix + "-" + String.valueOf(loopCounter.getAndIncrement());
		watch.start(taskName);
	}

	@Bean
	public StopWatch watch() {
		return new StopWatch();
	}
}


실행(local)

현재 설정되어 있는 상태로 수행을 합니다.

아래처럼 공통 설정인 timerName는 exampleTimer로 찍히면서 

프로파일별 설정을 따라 localTask가 1초 마다 찍히고 있습니다.


  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v1.4.0.RELEASE)


2016-09-12 13:28:03.434  INFO 6600 --- [           main] net.donnert.spring.boot.Application      : Starting Application on ezen-PC with PID 6600 (D:\Java\workspace\Ezens\paynow_simulator\spring.boot\target\classes started by donne in D:\Java\workspace\Ezens\paynow_simulator\spring.boot)

2016-09-12 13:28:03.437  INFO 6600 --- [           main] net.donnert.spring.boot.Application      : The following profiles are active: local

2016-09-12 13:28:03.498  INFO 6600 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@49d8c528: startup date [Mon Sep 12 13:28:03 KST 2016]; root of context hierarchy

2016-09-12 13:28:04.442  INFO 6600 --- [           main] net.donnert.spring.boot.Timer            : exampleTimer init

.....

...

2016-09-12 13:28:08.617  INFO 6600 --- [pool-1-thread-1] net.donnert.spring.boot.Timer            : StopWatch '': running time (millis) = 4170

-----------------------------------------

ms     %     Task name

-----------------------------------------

00166  004%  

01002  024%  localTask-0

01000  024%  localTask-1

01002  024%  localTask-2

01000  024%  localTask-3



실행(dev)

application.yml의 3번째 라인의 active: local을 active: dev로 바꿔줍니다.

아래처럼 공통 설정인 timerName는 exampleTimer로 찍히면서 

프로파일별 설정을 따라 devTask가 5초 마다 찍히고 있습니다.

  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v1.4.0.RELEASE)


2016-09-12 13:30:32.465  INFO 10976 --- [           main] net.donnert.spring.boot.Application      : Starting Application on ezen-PC with PID 10976 (D:\Java\workspace\Ezens\paynow_simulator\spring.boot\target\classes started by donne in D:\Java\workspace\Ezens\paynow_simulator\spring.boot)

2016-09-12 13:30:32.468  INFO 10976 --- [           main] net.donnert.spring.boot.Application      : The following profiles are active: dev

2016-09-12 13:30:32.521  INFO 10976 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@65efb4be: startup date [Mon Sep 12 13:30:32 KST 2016]; root of context hierarchy

2016-09-12 13:30:33.379  INFO 10976 --- [           main] net.donnert.spring.boot.Timer            : exampleTimer init

.....

...

2016-09-12 13:30:48.542  INFO 10976 --- [pool-1-thread-1] net.donnert.spring.boot.Timer            : StopWatch '': running time (millis) = 15158

-----------------------------------------

ms     %     Task name

-----------------------------------------

00154  001%  

05001  033%  devTask-0

05001  033%  devTask-1

05002  033%  devTask-2


마치며

스프링에서 프로파일은 콤마로 구분하여 여러개를 해도 됩니다.

자바에서 context.getEnvironment().getActiveProfiles()를 하면 현재 설정된 프로파일들을 가져올 수 있습니다.

이를 응용하여 확장이 용이한 프로그램 개발이 가능해집니다.


2016/09/19 - [개발/JAVA] - 스프링 부트(Spring boot)에서 logback 적용하기


  Comments,   0  Trackbacks
댓글 쓰기
명동교자

1년에 한두번쯤은 방문하는 명동교자입니다.

명동에 본점과 2호점 둘다 있습니다.


계산은 선불로 진행되며 식사 후 입가심을 위한 껌을 미리 줍니다.

메뉴는 칼국수, 비빔국수, 만두, 콩국수 4가지입니다.

그 중 저희는 기본세트(?)인 칼국수1+만두1을 주문합니다.


반찬

반찬은 김치 하나 덜렁 나옵니다.

이 김치가 굉장히 자극적이고 마늘맛이 강합니다.

호불호가 많이 갈리는 김치.


칼국수(8000원)

불맛이 살짝 느껴지는 칼국수입니다.

기름진 고기육수 느낌으로 진한 국물입니다.


만두(10000원)

칼국수보다 비싼 만두입니다.

속이 꽉찬 고기만두가 맛이 꽤 괜찮습니다.

전 이놈이 맛나네요.


리필

명동교자는 무한리필입니다.  종류는 위처럼 밥, 면사리, 국물

커플이 가신다면 칼국수+만두 시킨 후 면,밥을 리필해서 드시면 되겠습니다.


총평

가격이 그리 싼편은 아니지만 1년에 한두번 맛나게 먹고 오는 집입니다.

워낫 유명 맛집이다보니 평도 많은데 안 드셔보신 분은 한번 방문해보셔도 괜찮을 것 같습니다.


위치

  • 영업시간 : 10:30 ~ 21:30
  • 휴무일 : 연중무휴

이 장소를 Daum지도에서 확인해보세요.
서울 중구 명동2가 25-2 | 명동교자 본점
도움말 Daum 지도

'맛집' 카테고리의 다른 글

합정 라멘집 길라멘  (0) 2018.05.04
상수 라멘트럭  (0) 2016.10.10
아우라지 삼산점  (0) 2016.10.07
더 파스텔라(THE PASTELA!)  (0) 2016.09.18
명동교자  (1) 2016.09.12
  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트(Spring boot)에서 프로퍼티 사용하기

개요

개발을 하다보면 당연하지만 properties 파일을 사용합니다.

간단하게 스프링 부트에서 사용하는 방식을 살펴보겠습니다.

마찬가지로 이전 글과 이어집니다.

2016/09/07 - [개발/JAVA] - 스프링 부트(Spring boot)로 scheduling 개발하기


프로퍼티 생성

new-Source Folder를 선택하여 src/main/resources폴더를 생성합니다.

그리고 생성된 폴더에 application.properties만들고 다음과 같이 작성합니다.

spring.task.fixedDelay=2000

spring.task.name=donnert



Timer 수정

package net.donnert.spring.boot;

import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
public class Timer {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	private AtomicInteger loopCounter = new AtomicInteger();
	
	@Autowired
	private StopWatch watch;
	
	@Value("${spring.task.name}")
	private String taskNamePrefix;
	
	@PostConstruct
	public void init() {
		watch.start();
	}

	@Scheduled(fixedDelayString = "${spring.task.fixedDelay}")
	public void tick() throws InterruptedException{
		watch.stop();
		logger.info(watch.prettyPrint());
		String taskName = taskNamePrefix + "-" + String.valueOf(loopCounter.getAndIncrement());
		watch.start(taskName);
	}

	@Bean
	public StopWatch watch() {
		return new StopWatch();
	}
}


마무리

Application.java를 돌려보면 아래처럼 설정에서 읽어돠 2초마다 수행이 된 것을 볼 수 있습니다.

application.properties는 스프링 부트에서 기본으로 읽어오는 프로퍼티입니다.

-----------------------------------------

ms     %     Task name

-----------------------------------------

00157  002%  

02000  020%  donnert-0

02002  020%  donnert-1

02002  020%  donnert-2

02001  020%  donnert-3

02000  020%  donnert-4


  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트(Spring boot)로 scheduling 개발하기

2016/09/07 - [개발/JAVA] - 스프링 부트(Spring boot)로 개발하기


위에서 기본적인 부트 환경이 세팅 되었으니 간단한 스케줄링 프로그램을 만들어보도록 한다.

매초마다 로깅을 하거나 배치처럼 작동할 수 있는 예제를 작성해본다.

스케줄링 설정
Application에 @EnableScheduling어노테이션을 달아준다.
package net.donnert.spring.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

Timer 소스 작성
package net.donnert.spring.boot;

import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
public class Timer {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	private AtomicInteger loopCounter = new AtomicInteger();
	
	@Autowired
	private StopWatch watch;
	
	@PostConstruct
	public void init() {
		watch.start();
	}

	@Scheduled(fixedDelayString = "1000")
	public void tick() throws InterruptedException{
		watch.stop();
		logger.info(watch.prettyPrint());
		String taskName = "task-";
		taskName = taskName + String.valueOf(loopCounter.getAndIncrement());
		watch.start(taskName);
	}

	@Bean
	public StopWatch watch() {
		return new StopWatch();
	}
}
@Scheduled어노테이션을 통해 작업이 끝난 후 1초 후 다시 작업을 시작한다.
fixedRateString의 경우 이전 작업이 끝나지 않아도 1초마다 작업을 시작한다.


타이머 돌리면서 카운트 올리는게 끝이다.

작업 결과는 다음과 같다.  각각의 작업이 정확히(?) 1초 후 다시 시작되는걸 볼 수 있다.

2016-09-07 16:03:56.843  INFO 10640 --- [pool-1-thread-1] net.donnert.spring.boot.Timer            : StopWatch '': running time (millis) = 9188

-----------------------------------------

ms     %     Task name

-----------------------------------------

00178  002%  

01000  011%  task-0

01002  011%  task-1

01001  011%  task-2

01001  011%  task-3

01001  011%  task-4

01002  011%  task-5

01001  011%  task-6

01001  011%  task-7

01001  011%  task-8


마무리

@Scheduled의 cron속성으로 크론탭처럼(* * * * *) 설정도 가능하다.

야밤에 배치를 돌리거나 간단한 작업을 할 수 있는 프로그램이 끝났다.

심지어 우리는 logback 설정도 안했는데 쓰고있다.

이게 스프링 부트의 매력이다.


다음장으로 이어집니다

2016/09/08 - [개발/JAVA] - 스프링 부트(Spring boot)에서 프로퍼티 사용하기


  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트(Spring boot)로 개발하기

프로젝트 생성

new-project-Maven Project를 생성한다.

groupId와 artifactId를 적고 프로젝트 생성을 하면 이미지처럼 나오게 된다.

(그냥 아무 프로젝트 만들어서 우클릭-configure-convert to maven project로 해도 된다)


Spring boot 라이브러리 추가

pom.xml을 열어서 dependencies와 동일 레벨로 parent를 추가한다.

  
    org.springframework.boot
    spring-boot-starter-parent
    1.4.0.RELEASE
   

dependencies 하위 항목으로 다음을 추가한다.

        
	        org.springframework.boot
	        spring-boot-starter
        


메인 소스 작성

Application 클래스를 생성하여 다음과 같이 작성 해준다.

package donnert.spring.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

테스트

실행을 해보면 다음과 같이 스프링이 돌아가는걸 볼 수 있다.

아무것도 없는 기본 예제지만 스프링 기반의 환경(?)이 만들어 졌다.


다음글로 계속..

2016/09/07 - [개발/JAVA] - 스프링 부트(Spring boot)로 scheduling 개발하기



  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v1.3.5.RELEASE)


2016-09-07 11:06:27.631  INFO 5216 --- [           main] net.donnert.spring.boot.Application      : Starting Application on ezen-PC with PID 5216 (D:\Java\workspace\Ezens\paynow_simulator\spring.boot\target\classes started by donne in D:\Java\workspace\Ezens\paynow_simulator\spring.boot)

2016-09-07 11:06:27.635  INFO 5216 --- [           main] net.donnert.spring.boot.Application      : No active profile set, falling back to default profiles: default

2016-09-07 11:06:27.718  INFO 5216 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6765f738: startup date [Wed Sep 07 11:06:27 KST 2016]; root of context hierarchy

2016-09-07 11:06:28.888  INFO 5216 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup

2016-09-07 11:06:28.907  INFO 5216 --- [           main] net.donnert.spring.boot.Application      : Started Application in 1.674 seconds (JVM running for 2.058)

2016-09-07 11:06:28.908  INFO 5216 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6765f738: startup date [Wed Sep 07 11:06:27 KST 2016]; root of context hierarchy

2016-09-07 11:06:28.910  INFO 5216 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown



  Comments,   0  Trackbacks
댓글 쓰기
난수, random 문자열, 숫자 만들기

잘 만들어진거 있으니 사서 고생하지 말자


아파치 commons-lang쪽에 있다


// 1. 숫자
RandomStringUtils.random(10, false, true);
RandomStringUtils.randomNumeric(10);

// 2. 문자
RandomStringUtils.random(10, true, false);
RandomStringUtils.randomAlphabetic(10);

// 3. 섞어
RandomStringUtils.random(10, true, true);


  Comments,   0  Trackbacks
댓글 쓰기