기존 @Component의 기본 초기화 설정은 Eager이다. Eager일때는 스프링 어플리케이션을 실행할 때 모든 빈들을 초기화 하는 것이다. 하지만
1. 시작시 어플리케이션의 시작 지연을 조금이라도 줄이고 싶을 때
2. 메모리 사용량을 줄이고 싶을 때
가 있을 것이다.
그럴때는 @Lazy옵션을 사용 하면 된다.
@Lazy옵션을 사용하는 방법은 다음과 같다
@Component
@Lazy(value = true)//@Lazy 도 가능
Class class A{
기타 코드들
}
이렇게 해주면 SpringApplication을 시작할 때 빈이 초기화 되지 않고 해당 빈을 사용할 때 초기화가 된다.
Lazy와 Eager를 간단히 도표로 정리하면
| 목록 | Lazy | Eager |
|---|---|---|
| 초기화 시점 | 빈이 최초로 사용될때 | 어플리케이션이 시작될때 |
| Default여부 | X | O |
| 사용법 | @Lazy 또는 @Laxy(value=true) | @Lazy생략 또는 @Laxy(value=false) |
| 초기화중 에러발생시 | Runtime Exception | 어플리케이션이 시작도 안됨 |
| 권장? | X | O |
이된다.
@Scope란 빈의 범위를 설정해주는 것으로 빈 객체를 하나만 생성할 지 아니면 여러개 생성할지 설정해주는 것이다. 생성법에는 Prototype 과 SingleTone이 있다.
싱글톤은 단 하나의 빈 객체만 생성하여 이를 계속하여 사용 하는 것이며 Prototype은 빈을 요청할 때 마다 새로운 빈 객체를 생성하여 리턴해준다.
빈을 정의할 때 @Scope를 따로 정의 하지 않으면 기본은 싱글톤이다.
| 목록 | Prototype | Singletone |
|---|---|---|
| 인스턴스 | 많음 | 오직 하나 |
| Default여부 | X | O |
| 사용법 | @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) | @Scope(value=ConfigurableBeanFactory.SCOPE_SINGLETONE) |
| 권장사용법 | 하나의 정보를 유지할 필요 없을때 | 하나의 세션정보를 유지할 필요가 있을 때 |
이때 Java Singletone과 Spring Singletone에는 차이가 있다.
Java Singletone은 JVM에 하나, Spring Singletone은 스프링 어플리케이션이 실행되는 Spring IOC Container당 하나이다.
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//ConfigurableBeanFactory.SCOPE_SINGLETONE 하면 싱글톤이 된다
@Component
class A{
////구현 내용들
이렇게 해주면 빈에서 반환되는 모든 객체들은 서로 다른 객체가 된다.
이름에서 알 수 있듯이 Post(이후에)+Construct(생성) 생성 이후에 바로 실행될 함수를 지정해주는 어노테이션을 의미한다.
만약 다음과 같은 코드가 있으면
@Component
class A{
@Autowired
private B b;
public A(B b){
this.b = b;
System.out.println("B is injected");
}
}
@Component
class B{
public B(){
System.out.println("B is created");
}
}
의 실행 결과는
B is created
B is injected
기타 코드들 수행 내역
가 된다.
그런데 여기에
@Component
class A{
@Autowired
private B b;
public A(B b){
this.b = b;
System.out.println("B is injected");
}
}
@Component
class B{
public B(){
System.out.println("B is created");
}
@PostConstruct
public void ImReady(){
System.out.println("B is ready");
}
}
를 해주면 실행 결과는
B is created
B is Ready
B is injected
기타 코드들 수행 내역
가 된다.
B가 생성된 후 바로 ImReady가 실행되는 것이다. 이렇듯 Constructor에서 실행하지 못한 초기화 로직을 따로 실행시킬 때 사용 할 수 있다.
PreDestroy는 PostConstrcutor와는 달리 빈 객체가 Destroy되기 전에 실행되는 로직을 정의한다.
@Component
class A{
@Autowired
private B b;
public A(B b){
this.b = b;
System.out.println("B is injected");
}
}
@Component
class B{
public B(){
System.out.println("B is created");
}
@PreDestroy
public void ImReady(){
System.out.println("B is Dead!");
}
}
를 해주면
B is created
B is Injected
//기타 실행 내용들
<== B 빈 객체 삭제
B is Dead
//종료 로그
가된다.