스프링의 컨테이너는
bean의 생명주기 관리와 의존성 주입을 담당하여,
개발자가 로직에 집중할 수 있도록 해준다.
(객체의 소멸과 생성을 프레임워크가 대신 처리한다. )
□ 콜백이란?
주로 콜백함수를 부를 때 사용하는 용어다.
콜백함수를 등록하면 특정 이벤트가 발생했을 때 해당 메서드가 호출된다.
콜백 함수는
DB연결, 네트워크 소켓 연결과 같이 시작 시점에 미리 연결한 뒤
종료 시점에 연결을 종료해 객체의 초기화 & 종료 작업이 필요한
커텍션풀의 connection/disconnect 같은 작업에 사용된다.
□ 빈 생명주기 콜백의 필요성
스프링 빈도 위와 같이 초기화/종료 작업을 나눠서 진행한다.
즉, 객체 생성 --> 의존성 주입 라이프 사이클을 가진다.
(데이터를 사용하기 위해서는 의존관계 주입이 선행되어야 한다.)
■ 빈 생명주기 콜백
스프링 컨테이너가
bean의 생성 및 소멸 단계에서 호출하는 메서드
-> 개발자는 bean이 생성되거나 소멸될 때
필요한 초기화 작업 또는 마무리 작업을 수행할 수 있다.
□ 의존성 주입
xml 설정파일이나 @Bean 어노테이션으로 정의된 클래스를 bean으로 등록한다.
- 생성자 주입 : 객체 생성, 의존관계 주입이 동시에 일어난다.
@Controllerpublic class CocoController {
private final CocoService cocoService;
public CocoController(CocoService cocoService) {
this.cocoService = cocoService;
}
}
따라서
1. null 주입하지 않는 한 NullPointException은 발생하지 않는다.
2. 컴파일 타임에 오류 확인 용이(의존관계에 대한 내용을 외부에 노출).
- 세터, 필드 주입 : 객체 생성 -> 의존 관계 주입 단계로 나누어 생명주기가 진행된다.
@Controllerpublic class CocoController {
private CocoService cocoService;
@Autowired
public void setCocoService(CocoService cocoService) {
this.cocoService = cocoService;
}
}
따라서
생성자 주입과 다르게
Controller 객체를 만들 때 Service 객체와 의존관계 없어도 Controller 객체를 만들 수 있다.
■ 스프링 빈 이벤트 라이프 사이클
스프링 IoC 컨테이너 생성
-> 스프링 Bean 생성
-> 의존관계 주입
-> 초기화 콜백 메서드 호출
-> 사용
-> 소멸 전 콜백 메서드 호출
-> 스프링 종료
생성자는 파라미터를 받고, 메모리를 할당해서 객체를 생성하는 책임
but
초기화는 이렇게 생성된 값을 활용해 외부 커넥션을 연결하는 등 무거운 동작을 수행
따라서 객체를 생성하는 부분과 초기화하는 부분을 명확하게 나누는 것이 유지보수 관점에서 좋다.
(초기화 작업 간단하고 단순한 경우에는 생성자에서 한 번에 처리하는게 나을 수 있다.)
■ 빈 생명주기 콜백 3가지
스프링은 인터페이스,
설정 정보 활용,
@PostConstruct/@PreDestory 어노테이션 사용
등 크게 3가지 방법으로 빈 생명주기 콜백을 지원
스프링 인터페이스 사용
Initalizingean 인터페이스를 구현 후,
afterPropertiesSet(), destroy()메서드에 코드를 작성
@Component
class MySpringBean implements InitializingBean {
@Override
public void afterPropertiesSet() {
//...
}
}
@Component
class MySpringBean implements DisposableBean {
@Override
public void destroy() {
//...
}
}
단점
- 코드가 스프링에 의존 (스프링 전용 인터페이스)
- 메서드의 이름을 변경할 수 없음
- 외부 라이브러리에 적용이 불가능
Bean 어노테이션의 어트리뷰트 사용
Bean(initMethod = "init", destoryMethod = "close")와 같이 설정 정보에 메서드를 지정가능
@Configuration
class MySpringConfiguration {
@Bean(initMethod = "onInitialize", destroyMethod = "onDestroy")
public MySpringBean mySpringBean() {
return new MySpringBean();
}
}
인터페이스와 달리,
메서드 이름 자유롭게 지정 가능,
스프링 코드에 의존하지 않음
설정정보 이용하므로 코드 변경 불가한 외부 라이브러리에도 초기화 & 종료 메서드 적용 가능
@PostConstruct, @PreDestory 어노테이션
@Component
class MySpringBean {
@PostConstruct
public void postConstruct() {
//...
}
@PreDestroy
public void preDestroy() {
//...
}
}
<장점>
- 최신 스프링에서 가장 권장
- 어노테이션 하나만 붙이면 되므로 매우 간편
- 스프링이 아닌 다른 컨테이너에서도 동작
- 컴포넌트 스캔과 잘 어울림
@Component 어노테이션을 사용하면
클래스의 역할과 범위를 명시적으로 나타낼 수 있다.
@PostConstruct, @PreDestroy를 사용해 빈의 초기화와 소멸 메서드를 정의하면,
-> 스프링 애플리케이션의 컴포넌트들이 자연스럽게 등록되고,
초기화와 소멸 메서드가 관리된다.
<단점>
- 커스터마이징이 불가능한 외부 라이브러리에 적용 불가
(외부 라이브러리에 적용하기 위해서는 2번째 방법, @Bean의 initMethod와 destroy 속성을 사용)
'CS' 카테고리의 다른 글
CS)네트워크_네트워크 기초 (0) | 2024.05.22 |
---|---|
CS)Spring_11_스프링 MVC 패턴 (0) | 2024.05.20 |
S)Spring_10_스프링 컴포넌트 스캔 Component Scan & DI 자동 주입 (0) | 2024.04.15 |
S)Spring_09_스프링 컨테이너 (2) | 2024.04.10 |
S)Spring_09_스프링DI (0) | 2024.04.09 |