반응형

어플리케이션 내에서 스케쥴링 해야하는 일이 생긴다.

 

스프링부트에서 사용하려명 Main 클래스에 @EnableScheduling 을 추가해주면 된다.

 

@Component
public class Scheduler {

	@Scheduled(fixedDelay = 3000)
	public void excute() {
    	System.out.println("스케쥴러");
	}
}    

위의 코드는 3초마다 실행이 된다.

fixedDelay 는 스케쥴러가 끝나고 3초이고, fixedRate 는 3초마다 주기적으로 실행을 한다는 의미이다.

끝나는 시점이 중요하면 fixedDelay 를 사용해야 한다.

 

그리고 크론탭과 같은 문법 사용이 가능하다. 

ex)

@Scheduled(cron="*/30 * * * * *")

시간 설정 @scheduled(cron=" ") * 리눅스 crontab 과 같은 설정방법

ex> @Scheduled(cron="0 0 02 * * ?") = 매일 새벽2시에 실행

ex> @Scheduled(cron="0 0 02 2,20 * ?") = 매월 2일,20일 새벽2시에 실행


시간 설정 @scheduled(cron=" ")  * 리눅스 crontab 과 같은 설정방법

ex> @Scheduled(cron="0 0 02 * * ?") = 매일 새벽2시에 실행

ex> @Scheduled(cron="0 0 02 2,20 * ?") = 매월 2일,20일 새벽2시에 실행

 

스케쥴러 cron 양식

초 0-59 , - * / 

분 0-59 , - * / 

시 0-23 , - * / 

일 1-31 , - * ? / L W

월 1-12 or JAN-DEC , - * / 

요일 1-7 or SUN-SAT , - * ? / L # 

년(옵션) 1970-2099 , - * /

* : 모든 값

? : 특정 값 없음

- : 범위 지정에 사용

, : 여러 값 지정 구분에 사용

/ : 초기값과 증가치 설정에 사용

L : 지정할 수 있는 범위의 마지막 값

W : 월~금요일 또는 가장 가까운 월/금요일

# : 몇 번째 무슨 요일 2#1 => 첫 번째 월요일

 

예제) Expression Meaning 

초 분 시 일 월 주(년)

 "0 0 12 * * ?" : 아무 요일, 매월, 매일 12:00:00

 "0 15 10 ? * *" : 모든 요일, 매월, 아무 날이나 10:15:00 

 "0 15 10 * * ?" : 아무 요일, 매월, 매일 10:15:00 

 "0 15 10 * * ? *" : 모든 연도, 아무 요일, 매월, 매일 10:15 

 "0 15 10 * * ? : 2005" 2005년 아무 요일이나 매월, 매일 10:15 

 "0 * 14 * * ?" : 아무 요일, 매월, 매일, 14시 매분 0초 

 "0 0/5 14 * * ?" : 아무 요일, 매월, 매일, 14시 매 5분마다 0초 

 "0 0/5 14,18 * * ?" : 아무 요일, 매월, 매일, 14시, 18시 매 5분마다 0초 

 "0 0-5 14 * * ?" : 아무 요일, 매월, 매일, 14:00 부터 매 14:05까지 매 분 0초 

 "0 10,44 14 ? 3 WED" : 3월의 매 주 수요일, 아무 날짜나 14:10:00, 14:44:00 

 "0 15 10 ? * MON-FRI" : 월~금, 매월, 아무 날이나 10:15:00 

 "0 15 10 15 * ?" : 아무 요일, 매월 15일 10:15:00 

 "0 15 10 L * ?" : 아무 요일, 매월 마지막 날 10:15:00 

 "0 15 10 ? * 6L" : 매월 마지막 금요일 아무 날이나 10:15:00 

 "0 15 10 ? * 6L 2002-2005" : 2002년부터 2005년까지 매월 마지막 금요일 아무 날이나 10:15:00 

 "0 15 10 ? * 6#3" : 매월 3번째 금요일 아무 날이나 10:15:00

 

반응형
반응형

엔티티 클래스로 등록한 클래스지만, DB 테이블과는 별도로 기능이(추가 필드나 메소드) 필요한 경우가 있다.

 

예를 들어 DB 테이블에는 존재하지 않지만, 엔티티 클래스에는 등록되어 같이 운용하는 경우가 있다.

vo(엔티티) 에는 사용하지만 jpa 로 디비와 관련 없이 사용하고 싶을때!!

 

이럴 경우, DB 테이블에 간섭하지 않고, 엔티티 클래스 내부에서만 동작하게 하는 어노테이션을 사용한다.

 

@Transient 어노테이션을 사용하는데, 이 어노테이션은 하이버네이트의 jpa 패키지에 위치하고 있다.

@Transient 어노테이션을 사용한 필드나 메소드는 DB 테이블에 적용되지 않는다.

 

@Entity
public class Member {
    private Long memberId;
    private String password;
    @Transient
    private String confirmPassword;
    …
}

 

반응형
반응형

vscode 확장툴들이 너무나도 많이 생겨서 이전에는 인텔리제이 및 이클립스에서만 가능했던 자바 IDE 기능이 이제는 vscode 에서도 가능해졌습니다.

 

여러패키지가 있지만 스프링부트를 vscode 에서 사용하기 위해서는 2가지가 필요합니다.

1. Java Extension Pack(Micosoft)

  - java언어 지원 기능, 디버거, 테스트 실행, maven 프로젝트 관리 등의 확장을 패키징 한 패키지

2. Spring Boot Extension Pack(Pivotal)

  - spring 프레임워크에 적용할 수 있는 유용한 기능이 들어있는 패키지, 말그대로 팩이여서 여러가지 스프링부트 관련 확장 패키지가 포함되어 있습니다.

 

 

이클립스 기반 sts 를 만든 회사에서 Spring boot 패키지를 만든것 같습니다, (Pivotal)

 

여기서 주의 할 설정은 스프링부트가 구동되려면 설치한 자바 경로를 잡아줘야 합니다.

이거만 잘 진행된다면 바로 스프링구동이 됩니다.

 

java 확장도구 까지 설치했다면, 위와같이 settings 에서 

jdk 로 검색 후 setting.json 에서 자바 경로를 설정해 줍니다.

java home 만 설정해 주면 됩니다.

mac 의 경우 jdk 설치시

/Library/Java/JavaVirtualMachines/ 에 설치 되고 jdk 버젼 폴더 하위에

/Contents/Home 경로로 세팅해주면 모든 준비가 끝납니다.

 

 

그러면 vscode 패키지 명령어를 실행하면 됩니다.

spring initializr 를 실행하면 되는데, 이클립스 sts 로 스프링부트를 해보신분들이라면 이부분부터는 거의 UI 만 다르지 내용은 똑같습니다.

 

프로젝트가 생성되면 오른쪽 상단에 실행버튼이 생깁니다.

그 외에도 프로젝트 화면에 스프링부트 대쉬보드 및 메이븐 플로그인도 같이 사용가능하도록 UI 가 구성되어 있습니다.

다음은 스프링부트를 실행한 화면입니다.

반응형
반응형

spring boot mongodb connection 및 자동 _class 컬럼 insert 삭제 설정

몽고디비를 연결해주려면 스프링부트에서는 yml 설정에서 추가만 해도 되지만,

object 클래스를 넣어줄떄 자동으로 _class 라는 필드가 추가되게 된다.

_class 를 없애주려면 @Configuraion 으로 mongodb 세팅을 자바 코드로 설정을 해주어야 한다.

 

 

해당 내용은 스프링부트 spring-boot-stater-data-mongodb:2.3.3 RELEASE 버젼,

spring-data-mongodb:3.0.3 RELEASE 이다.

차이점은

spring-data-mongodb 2 버젼은 MongoDatabaseFactory 가 아니라 MongoDbFactory 이다.

3 버젼에서는 MongoDbFactory 가 deprecated 가 되어서 MongoDatabaseFactory 를 사용하자.

@Configuration
public class MongoDBConfig {

    @Value("${spring.data.mongodb.uri}")
    private String mongodb_uri;

    @Bean(name = "mongoTemplate1")
    public MongoTemplate mongoTemplate1()  {
        MongoClient mongoClient = MongoClients.create(mongodb_uri);
        MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(mongoClient, "collection1");
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(factory), new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return new MongoTemplate(factory, converter);
    }

    @Bean(name = "mongoTemplate2")
    public MongoTemplate mongoTemplate2()  {
        MongoClient mongoClient = MongoClients.create(mongodb_uri);
        MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(mongoClient, "collection2");
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(factory), new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return new MongoTemplate(factory, converter);
    }

    @Bean(name = "mongoTemplate3")
    public MongoTemplate mongoTemplate3()  {
        MongoClient mongoClient = MongoClients.create(mongodb_uri);
        MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(mongoClient, "collection3");
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(factory), new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return new MongoTemplate(factory, converter);
    }

}

다음과 같이 document 가 여러개이면 document 마다 template 을 나누어서 빈을 등록해준다.

 _class 삭제방법

여기서 _class 를 없애는 방법은 위의 코드와 같이

converter.setTypeMapper(new DefaultMongoTypeMapper(null));

컨버터에 null 을 세팅을 기본으로 해주어야 한다.

 

방법은 여러가지가 있겟지만, 해당 방법이 코드량 적고 각각 document 마다 설정 가능하다는 점이 장점이다.

 

auto localhost 몽고 연결 수정

이대로만 하면 아마 spring boot 가 시작시 자동으로 localhost 27017 로 몽고디비가 연결을 시도한다.

이 점을 수정하려면 시작시에 자동으로 시작되는 class 를 제외시켜주면 된다.

@SpringBootApplication 에 exclude 에 MongoDataAutoConfiguration.class 를 추가해주자.

@SpringBootApplication(exclude = { MongoDataAutoConfiguration.class})
public class MongoApplication {

	public static void main(String[] args) {
		SpringApplication.run(MongoApplication.class, args);
	}

}

yml 파일도 설정해주자

spring:
  data:
    mongodb:
      uri: mongodb://아이디:비번@몽고디비url:27017

 

 

yml 로만 설정을 하게되면 스프링몽고디비 3 버젼에서는 로컬로만 연결이 됐다.

 

해결방법을 찾지 못해도 다음처럼 mongotemplate 을 구성한 이유도 있다.

@Value 로 설정값을 가져와서 연결하는 방법이다.

그래서 실질적으로 어플리케이션이 올라가면서 몽고디비 커넥션을 맺는방식은 아니고 빈을 생성시에 yml 에서 값을 가져와서 mongoTemplate 에 사용을 한다.

yml 에 굳이 계정정보를 넣지 않아도 되지만, 자바코드보다는 yml 에 설정값을 넣는 편이 낫다.

 

 

반응형
반응형

스프링 어플리케이션을 시작할때 어플리케이션이 뜰때 초기 구동시켜줘야하는 코드들이 있을 수 있다.

이 때 해결 방법이

CommandLineRunner, ApplicationRunner, @EventListener  방법으로 초기 실행코드를 구현 할 수 있다.

 

@Component //component scanning에 의한 방식으로 빈을 등록하는 방법 
public class MyCLRunner implements CommandLineRunner {

	@Override 
    public void run(String... args) throws Exception { 
   		System.out.println("CommandLineRunner Args: " + Arrays.toString(args));
    } 
}

또는 @Bean 으로 사용 가능 

@Bean 
public CommandLineRunner myCLRunner() { 
	return args -> System.out.println("Hello Lambda CommandLineRunner!!"); 
}

 

구동시 파라미터를 다음과 같이 받을 수 있다. 아래 방식은 ApplicationRunner 도 동일하다.

$ java -jar target/demo-0.0.1-SNAPSHOT.jar abc 123

2. ApplicationRunner 

CommandLineRunner 와 사용법은 똑같지만 다른 것은 파라미터 타입이 다른것 뿐이다.

ApplicationRunner 가 더 최근에 나온 방식이다.

@Component
public class DemoApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner Args: " + Arrays.toString(args.getSourceArgs()));
    }

}
@Bean 
public ApplicationRunner myApplicationRunner() { 
	return args -> System.out.println("Hello ApplicationRunner"); 
}

 

 

ApplicationRunner가 CommandLineRunner보다 일찍 실행된다.

다음과 같이 만든 초기구동 컴포넌트들이 실행순서가 이슈가 있을 경우 순서를 지정할 수 있다,

@Order(1)
@Component
public class DemoCommandLineRunner implements CommandLineRunner { ...

@Order(2)
@Component
public class DemoApplicationRunner implements ApplicationRunner { ...

3. @EventListener

이벤트 리스너가 최근에 나온 방식(4.2 이후)으로 이벤트를 연결해 초기 구동시 해당 클래스를 실행시킬 수 있다.

@SpringBootApplication public class SpringinitApplication { 
	public static void main(String[] args) { //ConfigurableApplicationContext : ApplicationContext를 코드에 의해서 재구성할 수 있도록 기능을 집어넣은 ApplicationContext. 
      ConfigurableApplicationContext ac = SpringApplication.run(SpringinitApplication.class, args); 
      ac.publishEvent(new MyEvent(ac,"My Spring Event")); 
    } 
    
    @EventListener(MyEvent.class) 
    public void onMyEvent(MyEvent myEvent){ 
    	System.out.println("Hello EventListener : " + myEvent.getMessage()); 
    } 
    static class MyEvent extends ApplicationEvent { 
   		private final String message; //원래 String message는 없는 건데 추가한 것임. 
        public MyEvent(Object source, String message) { 
        	super(source); this.message = message; 
  		} 
        public String getMessage(){ 
        	return message; 
        } 
    } 
}

 

여러개 클래스의 경우 다음과 같이 실행할 수 있다.

@EvnetListener({MyEvent.class, ApplicationReadyEvent.class})

참고문헌https://www.daleseo.com/spring-boot-runners/ [스프링 부트 구동 시점에 특정 코드 실행 시키기] 
https://jeong-pro.tistory.com/206[스프링 부트 애플리케이션에서 초기화 코드 3가지 방법]

반응형
반응형

2.3의 새로운 기능

종속성 업그레이드

Spring Boot 2.3 에 새로 추가된 내용

  • Spring Data Neumann
  • Spring HATEOAS 1.1
  • Spring Integration 5.3
  • Spring Kafka 2.5
  • Spring Security 5.3
  • Spring Session Dragonfruit

또한 가능한 경우 타사 라이브러리의 안정적인 최신 릴리스로 업그레이드했습니다.이 릴리스에서 주목할만한 타사 종속성 업그레이드 중 일부는 다음과 같습니다.

  • Cassandra Driver 4.6
  • Couchbase Client 3.0
  • Elasticsearch 7.6
  • Kafka 2.5
  • Micrometer 1.5
  • MongoDB 4.0

자바 14 지원

Spring Boot 2.3은 Java 14를 지원하면서도 Java 11 및 8과 호환됩니다.

도커 지원

Spring Boot 2.3에는 Spring Boot 응용 프로그램을 Docker 이미지로 패키지화하는 데 도움이되는 흥미로운 새로운 기능이 추가되었습니다.Cloud Native Buildpack을
사용하여 Docker 이미지 빌드를 지원하며목표와작업을통해 Maven 및 Gradle 플러그인에 추가되었습니다.Paketo자바 buildpack는 이미지를 만드는 데 기본적으로 사용됩니다.spring-boot:build-imagebootBuildImage

또한 컨텐츠를 레이어로 분리하여 jar 파일을 빌드하는 기능이 Maven 및 Gradle 플러그인에 추가되었습니다.

Graceful shutdown (정상종료)

4 개의 내장 웹 서버 (Jetty, Reactor Netty, Tomcat 및 Undertow)와 반응 형 및 서블릿 기반 웹 애플리케이션 모두에서 정상 종료가 지원됩니다.유예 기간이 구성되면 종료시 웹 서버는 더 이상 새 요청을 허용하지 않으며 활성 요청이 완료 될 때까지 유예 기간까지 기다립니다.

Liveness and Readiness probes

Spring Boot 2.3은 애플리케이션의 가용성에 대한 기본 지식을 보유하고있어 애플리케이션의 존재 여부와 트래픽을 처리 할 준비가되었는지 추적합니다.확인이 블로그 게시물

스프링 데이터 노이만

Spring Boot 2.3은 수많은 주요 버전 및 드라이버 업그레이드가 포함 된Spring Data Neumann과 함께 제공됩니다.이 릴리스에는 R2DBC에 대한 GA 지원도 추가되었습니다.

다른 변화들

릴리스 노트에문서화되어있는 다른 많은 변경 사항 및 개선 사항이 있습니다.더 이상 사용되지 않는 클래스 및 다음 버전에서 제거 할 메소드 목록도 찾을 수 있습니다.

참고문헌

https://spring.io/blog/2020/05/15/spring-boot-2-3-0-available-now [스프링 2.3블로그 원문]
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes [2.3 릴리즈 노트]

반응형
반응형

mockMvc 사용준비

@Autowired
SampleController sampleController;

private MockMvc mockMvc;

@Before
public void 기본() throws Exception{
	mockMvc = MockMvcBuilders.standaloneSetup(sampleController).build();

}

 

기본 get 방식 test

@Test
public void get_sample() throws Exception{
    RequestBuilder reqBuilder = MockMvcRequestBuilders.get("/test" + 1)
    .param("param1", param1)
    .param("param2", param2)
    .param("param3", param3);
    this.mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
}

post @requestBody 요청

public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

@Test
public void 제이슨_바디리퀘스트() throws Exception{
   RequestBuilder reqBuilder = MockMvcRequestBuilders.post("/test/" + 1)
                 .header("header1", header1)
                 .header("header2" , header2)
                 .contentType(APPLICATION_JSON_UTF8)
                 .content(requestJson);

   this.mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
}

메소드 사용법

andDO

요청에 대한 처리를 합니다. print() 메소드가 일반적입니다.

.andDo(print())

andExpert

예상값을 검증합니다. assert* 메소드들과 유사합니다.

// status 값이 정상인 경우를 기대하고 만든 체이닝 메소드 중 일부입니다.
.andExpect(status().isOk())
// contentType을 검증합니다.
.andExpect(content().contentType("application/json;charset=utf-8"))

andReturn

테스트 클래스에서 작성은 안했지만 테스트한 결과 객체를 받을 때 사용합니다.

MvcResult result = this.mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attributeExists("serverTime"))
.andReturn();
반응형
반응형

Transactions

마이바티스 스프링 연동모듈을 사용하는 중요한 이유중 하나는 마이바티스가 스프링 트랜잭션에 자연스럽게 연동될수 있다는 것이다.
마이바티스에 종속되는 새로운 트랜잭션 관리를 만드는 것보다는 마이바티스 스프링 연동모듈이 스프링의 DataSourceTransactionManager과 융합되는 것이 좋다.

설정을 하면 스프링에서 트랜잭션 가능

@Transactional 애노테이션과 AOP스타일의 설정 모두 지원한다. 하나의 SqlSession객체가 생성되고 트랜잭션이 동작하는 동안 지속적으로 사용될것이다. 세션은 트랜잭션이 완료되면 적절히 커밋이 되거나 롤백될것이다.

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
</bean>

트랜잭션 관리자에 명시된 DataSource가 SqlSessionFactoryBean을 생성할때 사용된 것과 반드시 동일한 것이어야 하는 것만 꼭 기억하자. 그렇지 않으면 트랜잭션 관리가 제대로 되지 않을것이다.

Transactions 주의사항

@Transactional 어노테이션은 Proxy기반이므로 내부 메소드 호출인 경우 트랜잭션이 적용되지 않는다. 즉 현재 클래스의 메소드가 아닌 다른 클래스의 메소드에 트랜잭션을 걸어야 한다.
서비스 메소드에만 가능!!. private 메소드에는 안됨!

문서

http://www.mybatis.org/spring/ko/transactions.html

참고문헌

http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=500

반응형

+ Recent posts