일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 401오류
- n+1
- springSecurityFilterChain 오류
- 쿠키란
- 세션vs쿠키
- 필터vs인터셉터
- optional
- 유연한 컨트롤러1 - v5
- 구글 보안 api 활용
- .orelseThrow
- @Controller
- 필터의 정의
- jpa
- controller
- SpringMVC
- Testcode
- 쿠키의 정의
- filter vs interceptor
- abap value in field Data Class error
- 세션의 정의
- spring MVC
- BindingResult
- 김영한
- java.lang.AssertionError
- Validation
- spring
- application-properties
- 세션이란
- 인터셉터의 정의
- MVC
- Today
- Total
ABAP DUMP ERROR 24시
빈 생명주기 콜백 정리 본문
# 인프런 김영한의 스프링 핵심 원리 - 기본편을 개인적으로 정리한 글입니다.
정리
Q. 빈 라이프 사이클이 왜 필요해?
데이터베이스 커넥션 풀이나, 네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고,
애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요하다.
=> 시작 시점에는 미리 연결해두고 종료시점에는 모두 종료시키는 역할이 필요하다!
Q. 스프링 빈의 이벤트 라이프사이클 순서가 뭐야?
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료
우리는 초기화 콜백과 소멸전 콜백을 신경써야한다.
Q.스프링의 빈 생명주기 콜백 크게 3가지 방법이 뭐야?
1.인터페이스(InitializingBean, DisposableBean) // implements를 사용후, @override 해서 사용한다.
2.설정 정보에 초기화 메서드, 종료 메서드 지정 //@Bean내부에 "init"과 destroyMethod를 지원해서 사용한다.
3.@PostConstruct, @PreDestroy 애노테이션 지원 //@PostConstruct, @PreDestroy를 사용한다. ///이거 써라!
Q.결론
@PostConstruct, @PreDestroy 애노테이션을 사용하자.
코드를 고칠 수 없는 외부 라이브러리를 초기화, 종료해야 하면 @Bean 의 initMethod , destroyMethod 를 사용하자.
살펴보기
Q. 빈 라이프 사이클이 왜 필요해? // Code로 확인하기
public class NetworkClient {
private String url;
public NetworkClient(){
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메세지");
}
public void setUrl(String url){
this.url =url;
}
//서비스 시작시 호출
public void connect(){
System.out.println("connect = " + url);
}
public void call(String message){
System.out.println("call = " + url + "message = " + message);
}
//서비스 종료시 호출
public void disconnect(){
System.out.println("close = " + url);
}
시작시 connect를 사용해서 호출하고 종료시 disconnect를 사용해서 종료하는 알고리즘을 만들었다고 가정하자!
그 후 기능들을 적용 시킬 TEST Code를 말들어 살펴보면,
public class BeanLifeCycleTest {
@Test
public void lifeCycleTest() {
ConfigurableApplicationContext ac = new
AnnotationConfigApplicationContext(LifeCycleConfig.class);
NetworkClient client = ac.getBean(NetworkClient.class);
ac.close(); //스프링 컨테이너를 종료, ConfigurableApplicationContext 필요
}
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
}
LifeCycleTest() 안에 ConfigurableApplicationContext 를 통해 LifeCycleConfig.class를 의존관계를 가져오고,
AnnotationConfigApplicationContext를 통해 @configuration 내의 @Bean을 읽어온다.
하지만 결과는?
생성자 호출,
url = null
connect: null
call: null message = 초기화 연결 메시지
객체를 생성하는 단계에는 url이 없없기 때문에 null 이 발생하였고,
객체를 생성한 다음에 외부에서 수정자 주입을 통해서 setUrl() 이 호출되어야 url이 존재하게 된다.
Q.스프링의 빈 생명주기 콜백 크게 3가지 방법이 뭐야? // Code
1.인터페이스(InitializingBean, DisposableBean) // implements를 사용후, @override 해서 사용한다.
public class NetworkClient implements DisposableBean, InitializingBean{
private String url;
public NetworkClient(){
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메세지");
}
public void setUrl(String url){
this.url =url;
}
//서비스 시작시 호출
public void connect(){
System.out.println("connect = " + url);
}
public void call(String message){
System.out.println("call = " + url + "message = " + message);
}
//서비스 종료시 호출
public void disconnect(){
System.out.println("close = " + url);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("NetworkClient.afterPropertiesSet");
connect();
call("초기화 연결 메세지");
}
@Override
public void destroy() throws Exception {
System.out.println("NetworkCline.destory");
disconnect();
}
}
2.설정 정보에 초기화 메서드, 종료 메서드 지정 //@Bean내부에 "init"과 destroyMethod를 지원해서 사용한다.
public class Bean_init_close_lifecycle {
private String url;
public Bean_init_close_lifecycle(){
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메세지");
}
public void setUrl(String url){
this.url =url;
}
//서비스 시작시 호출
public void connect(){
System.out.println("connect = " + url);
}
public void call(String message){
System.out.println("call = " + url + "message = " + message);
}
//서비스 종료시 호출
public void disconnect(){
System.out.println("close = " + url);
}
public void init() {
System.out.println("Bean_init_close_lifecycle.init");
connect();
call("초기화 연결 메세지");
}
public void close() {
System.out.println("Bean_init_close_lifecycle.close");
disconnect();
}
}
다음과 같이 init 메소드와 close()메소드를 만들어 준다음!
public class Bean_init_close_lifecycle_test {
@Test
public void lifeCycleTest(){
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(BeanLifeCycleTest.LifeCycleConfig.class);
NetworkClient client = ac.getBean(NetworkClient.class);
ac.close();
}
@Configuration
static class LifeCycleConfig{
@Bean(initMethod = "init", destroyMethod = "close")
public Bean_init_close_lifecycle beanInitCloseLifecycle(){
Bean_init_close_lifecycle bean_init_close_lifecycle = new Bean_init_close_lifecycle();
bean_init_close_lifecycle.setUrl("https://hello-spring.dev");
return bean_init_close_lifecycle;
}
}
}
@Bean에 initMethod에는 init메소드를,
destoryMethod에는 close메소드를 넣는다.
3.@PostConstruct, @PreDestroy 애노테이션 지원 //@PostConstruct, @PreDestroy를 사용한다.
public class Bean_postConstructor_predistroy {
private String url;
public Bean_postConstructor_predistroy(){
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메세지");
}
public void setUrl(String url){
this.url =url;
}
//서비스 시작시 호출
public void connect(){
System.out.println("connect = " + url);
}
public void call(String message){
System.out.println("call = " + url + "message = " + message);
}
//서비스 종료시 호출
public void disconnect(){
System.out.println("close = " + url);
}
@PostConstruct
public void init() {
System.out.println("Bean_postConstructor_predistroy.init");
connect();
call("초기화 연결 메세지");
}
@PreDestroy
public void close() {
System.out.println("Bean_postConstructor_predistroy.close");
disconnect();
}
}
'[WEB]Back-end > Spring' 카테고리의 다른 글
import org.assertj.core.api.Assertions, 간편 기능 (0) | 2022.01.30 |
---|---|
조회 @Bean이 2개 이상일 때 NoUniqueBeanDefinitionException (0) | 2022.01.28 |
좋은 객체 지향 설계의 5가지 원칙(SOLID) (0) | 2022.01.25 |
@Componet, @Controller, @Service, @Repository가 뭐야? (0) | 2022.01.24 |
Spring을 왜 써? Java의 다형성은 뭐야? (0) | 2022.01.24 |