개발 (65)
스프링 부트(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


0  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)에서 프로퍼티 사용하기


0  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



0  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);


0  Comments,   0  Trackbacks
댓글 쓰기
Mybatis #과 $의 차이

PrepareStatment(#)와 Statment($)를 정확히 모르고 사용하시는 분들이 있어 정리해봤습니다.

 - 간혹 Statment를 숫자일때 사용한다.. 라고 생각하시는 분들고 계시고 정확한 의미를 모르는 분들이 계십니다.  정리된 내용 보시기 바랍니다.


1. #의 사용 (PrepareStatment)

 - #을 사용할 경우 오라클의 PreparedStatment를 사용하게 된다.


  예제(name=John)

   a. mybatis mapper

      SELECT NAME FROM TEST WHERE NAME=#{name}

   b. 오라클에서 받은 쿼리

      SELECT NAME FROM TEST WHERE NAME = ?


실제 수행 쿼리

SELECT NAME FROM TEST WHERE NAME='John'


2. $의 사용(Statment)

 - $는 간단히 스트링 자체를 변환(REPLACE)해 버린다


  예제(score=99)

   a. mybatis mapper 

      SELECT NAME FROM TEST WHERE SCORE=${score}

   b. 오라클에서 받은 쿼리 

      SELECT NAME FROM TEST WHERE SCORE=99


실제 수행 쿼리

SELECT NAME FROM TEST WHERE NAME=99


3. 차이

두 가지가 똑같아 보이지만 붉게 처리된 부분을 볼 경우 1번은 오라클에서 변수를 바인드 처리 하기 때문에

NAME 값이 달라질 경우 같은 쿼리로 인식하게 됩니다.

(반드시는 아니지만 일반적으로 오라클의 쿼리 파싱, 캐시 등의 이점으로 CPU 및 수행 속도 차이가 나게 됩니다)


2번의 경우 b부분을 봤을때 쿼리 자체가 변경되어 들어가기 때문에 SCORE가 다른값이 올 경우

오라클은 이를 완전 다른 쿼리로 인식하기 때문에 새로 파싱 등의 작업을 하게 되고 속도가 느려질 우려가 있습니다.


그럼 Statment의 경우 어떻때 쓰는게 좋을까요?


SELECT ${column_name} FROM SCORE


위 쿼리같이 Bind를 할수 없는 경우 Statment를 사용하게 됩니다.

하지만 문자열 자체가 변형되기 때문에 보안상 취약할 수 있습니다.


예를 들면 아래와 같은 경우입니다.

user를 'admin'--로 세팅, password='aaa'

SELECT * FROM USER WHERE ID=${user} AND PASSWORD=${password}

실제 수행 쿼리

SELECT * FROM USER WHERE ID='admin'-- AND PASSWORD='aaa'


녹색 부분이 주석처리되어 admin으로 접속이 가능하게 되었습니다.


'개발 > DB' 카테고리의 다른 글

Mybatis #과 $의 차이  (1) 2014.11.10
몽고DB 설치  (0) 2014.01.22
테이블 정보(컬럼 정보, 코멘트 등등)  (0) 2013.11.11
테이블 사이즈 구하기(컬럼 길이, 컬럼 길이 평균)  (0) 2013.03.12
[ORACLE] 달력  (0) 2012.09.14
[ORACLE] 디비 락 해제  (0) 2012.01.09
1  Comments,   0  Trackbacks
  • 행인
    안녕하세요 글 잘봐습니다 좋은 글 감사합니다~ 다만 글에 약간 오해의 소지가 있을 수 있어 글남겨요~ Java가 오라클은 맞습니다만, 잘 모르시는 분이 보시면 잘 이해를 못하실 것 같아요. java.sql 페키지의 PreparedStatement 객체(인터페이스)를 사용하고, 이 PreparedStatement는 MyBatis 없이 Java Servlet을 통해 웹개발을 할 때 SQL문을 만드는 객체입니다. 바인드 변수는 맨 처음 SQL문을 하드파싱하고, 실행계획 생성하고, 캐싱을합니다. 이 캐싱 된것을 반복적으로 재사용할 수 있어 좋습니다. 바인드 변수를 사용할 때 단점이 같은 조건이라도 다른 실행계획(예를 들어 조건에 따라 인덱스 스캔 또는 풀테이블 스캔이 유리함의 유동치)일 때 불리합니다.
댓글 쓰기
쉘 이용해서 자동 로그인하기

아래와 같은 쉘을 만들어서 실행해준다.

#!/usr/bin/expect -f
spawn ssh 111.111.111.111
expect "assword:"
send "thisispassword\r"
interact

'개발 > Linux/Server' 카테고리의 다른 글

쉘 이용해서 자동 로그인하기  (0) 2014.09.17
vmstat 파일에 쓰기  (0) 2014.08.25
shell 색상 입히기  (0) 2013.11.28
마지막으로 수정된 파일 tail 걸기  (0) 2013.11.13
서버 공인 및 사설 IP 확인  (0) 2013.08.21
방화벽 설정(iptables)  (0) 2013.06.19
0  Comments,   0  Trackbacks
댓글 쓰기
vmstat 파일에 쓰기

시스템 자원, CPU, 메모리 등을 파일로 기록하고 싶을때 사용한다.


아래와 같이 쓰면 된다. 1초마다로 설정해놨으니 숫자 바꾸면 된다.


$ vmstat 1 | xargs -I{} date '+%F %T {}'


결과는 아래처럼...

2014-08-25 14:57:10 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----

2014-08-25 14:57:10 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

2014-08-25 14:57:10 3  0  62624 134236  19884 4171812    0    0     0     0 10433 10042 42 22 36  0  0

2014-08-25 14:57:11 4  0  62624 132384  19892 4173124    0    0     0    60 7839 7459 38 10 52  0  0


당연한거지만 파일에 쓸경우 아래처럼..

$ vmstat 1 | xargs -I{} date '+%F %T {}' >> vmstat.log


콘솔 닫아도 적용되게 할려면 아래처럼 하자.

죽일 때는 kill을 이용하자

$ nohup vmstat 1 | xargs -I{} date '+%F %T {}' >> vmstat_log.txt &

[1] 5690

nohup: ignoring input and redirecting stderr to stdout

$ kill -9 5690

'개발 > Linux/Server' 카테고리의 다른 글

쉘 이용해서 자동 로그인하기  (0) 2014.09.17
vmstat 파일에 쓰기  (0) 2014.08.25
shell 색상 입히기  (0) 2013.11.28
마지막으로 수정된 파일 tail 걸기  (0) 2013.11.13
서버 공인 및 사설 IP 확인  (0) 2013.08.21
방화벽 설정(iptables)  (0) 2013.06.19
0  Comments,   0  Trackbacks
댓글 쓰기
datepicker 복사 문제

jquery 달력 사용 시 clone등을 통해 다이나믹하게 컨트롤 할 경우 문제가 많다.

아래처럼 해당 속성을 완벽하게 지워줘야 한다.

destroy후 아래처럼 기존에 남아있는 속성들을 전부 지워줘야 한다.

ID가 있는경우 removeAttr(id)를 이용해 id도 지워주자.


var clone = $(this).clone();

     clone .find('.startDate').siblings('.ui-datepicker-trigger,.ui-datepicker-apply').remove();

     clone

       .removeClass('hasDatepicker')

       .removeData('datepicker')

       .unbind()

 .datepicker();


특히 굵게 처리된 부분을 찾지 못해서 이미지가 두개씩 뜨는 삽질을 할 수도 있다.


2014.04.11 추가

아래처럼 hasClass를 확인하여 완벽하게 datepicker속성을 날려버린 후 재사용하자

       if($(this).hasClass('hasDatepicker') == true) {

            $(this).siblings('.ui-datepicker-trigger,.ui-datepicker-apply').remove();

            $(this)

            .removeAttr('id')

            .removeClass('hasDatepicker')

            .removeData('datepicker')

            .unbind();

       }

'개발 > js/jQuery' 카테고리의 다른 글

datepicker 복사 문제  (1) 2014.03.27
JSON 파싱 및 필드 추가 삭제  (0) 2014.01.30
이메일 유효성 정규식 검사  (0) 2013.05.03
[jQuery] 인풋 전체 선택  (0) 2013.04.03
체크박스 전체 선택 해제하기  (0) 2013.03.25
1  Comments,   0  Trackbacks
댓글 쓰기
이클립스 플러그인 추천

IndentGuide

텍스트 에디터에 세로줄을 만들어준다

노트패드++랑 비슷하게..

* 내용참고

http://sschaef.github.io/IndentGuide/

* 설치

Help->Install New Software

http://sschaef.github.com/IndentGuide/update




CheckStylus

코딩 컨벤션을 검사해준다.  기왕이면 맞춰서 쓰자.

* 내용 참고

http://checkstyle.sourceforge.net/

http://forum.falinux.com/zbxe/index.php?document_srl=550586&mid=lecture_tip

http://dreamfactory7.tistory.com/201


EasyShell

마우스 우측버튼으로 탐색기 및 커맨드 창을 열어준다

* 내용 참고

http://marketplace.eclipse.org/content/easyshell?mpc=true&mpc_state=



Eclipse Color Theme

자세한 내용은 생략한다.

* 내용 참고

http://marketplace.eclipse.org/content/eclipse-color-theme?mpc=true&mpc_state=


Properties Editor

프로퍼티에 한글이 있다면 사용을 강추한다.

* 내용 참고

http://marketplace.eclipse.org/content/properties-editor?mpc=true&mpc_state=



'개발' 카테고리의 다른 글

web sequence diagram 오픈  (0) 2018.07.10
딴짓 오픈  (0) 2018.06.28
이클립스 플러그인 추천  (0) 2014.02.20
SecureCRT 한글 깨짐  (0) 2013.11.27
[HTML] 기본 context 경로 지정하기  (0) 2013.05.21
웹 포토샵  (0) 2012.01.18
0  Comments,   0  Trackbacks
댓글 쓰기
JSON 파싱 및 필드 추가 삭제

문자열 -> json -> 문자열


var str = { "result":"0000", "site":"donnert.net" }

var jsonObj = JSON.parse(str);

console.log( JSON.stringify(jsonObj) );


json 신규 객체 생성 후 사용, 속성 삭제


var jsonObj = {};

jsonObj ["result"] = "0000";

jsonObj ["site"] = "donnert.net";


delete jsonObj.site;



'개발 > js/jQuery' 카테고리의 다른 글

datepicker 복사 문제  (1) 2014.03.27
JSON 파싱 및 필드 추가 삭제  (0) 2014.01.30
이메일 유효성 정규식 검사  (0) 2013.05.03
[jQuery] 인풋 전체 선택  (0) 2013.04.03
체크박스 전체 선택 해제하기  (0) 2013.03.25
0  Comments,   0  Trackbacks
댓글 쓰기