Spring Bean
。Spring Context( = IoC Container )에 등록되어 관리되는 자바 객체
▶ IoC에 의해 개발자가 아닌, Framework에 의해 생성 및 관리
。Spring Bean은 개발자가 직접 제어가 불가능하고 오직 Spring Context에 의해 제어
。Spring Context내 Bean Repository에 객체로서 저장되어 Life Cycle와 Dependencies를 자동으로 관리
▶ 필요한 곳에 Auto-Wiring 후 Dependency Injection을 통해 주입

▶ Intellij에서 Spring Bean 선언 시 다음처럼 아이콘이 도출
Spring Bean의 기본 Scope는 싱글톤 패턴으로 관리된다
。자바 객체를 Spring Context로 Spring Bean으로서 등록 시 싱글톤 객체로서 관리됨.
▶ 어디서든 해당 Spring Bean을 의존성 주입 시 무조건 동일한 싱글톤 객체로 의존성 주입
싱글톤으로 등록된 Spring Bean은 특정 상황에 종속된 상태값으로서의 변수를 가지면 안된다.
。한 사람이 필요성에 의해 해당 클래스 객체 필드에 count 등을 가지도록 설정하면 해당 클래스는 Spring Bean으로 관리되므로 싱글톤이기 때문에, 다른 사람이 해당 의존성 주입 받으면 활용 할 수 없는 요소이기때문.
▶ 범용적으로 설계해야한다.
。단 상수는 가질 수 있다.
Spring Bean을 Spring Context에 등록하는 방법
。해당 방법을 정의한 Class들을 @ComponentScan에 의해 식별되어 Spring Bean으로 등록
1. @Configuration Class 내 @Bean Method를 등록하고 자바객체를 반환하도록 설정
。반환되는 자바객체는 Spring Bean으로 등록됨.
。@Bean Method에 매개변수 정의 시 해당 매개변수에 해당하는 Spring Bean을 Spring Bean으로부터 자동으로 의존성 주입
2. @Component 어노테이션을 선언
。@Configuration, @Service, @Repository, @Controller가 존재
Spring Bean과 POJO와 차이점
。Spring Conext에 의해 관리되는 모든 자바객체들은 모두 Spring Bean
▶ 관리되지않는 경우 POJO
。 Spring Bean의 경우 Spring Context 내 Bean Registry에서 Spring Context에 의해 생성 및 파괴
▶ 일반 POJO는 new를 통해 Heap 영역상에서 생성되어 GC에 의해 메모리 해제
A a = A()
A b = new A()

。 Spring Context로 등록된 A 클래스의 Spring Bean을 생성 시 new 없이 A a = A()를 선언
▶ Spring Context의 Bean Registry에서 가져와서 Auto-Wiring을 거쳐 DI를 통해 Spring Bean을 주입
Spring Bean의 초기화
Eager Initialization : default
。Spring Bean의 기본 초기화 방식으로서 주로 사용되는 방식
。Spring Context의 각각의 Spring Bean은 어플리케이션이 실행되는 즉시 초기화가 적용.
。Error 발생 시 어플리케이션이 실행 되지 않는다.
▶ 런타임 시 발생하는 Error을 즉각 확인이 가능하므로 사용을 권장
Lazy Initialization :
。@Lazy로 선언하여 Eager Init'을 억제하도록 설정
。@Lazy가 선언된 Spring Bean이 참조되거나 활용되는 시점에 초기화가 적용
。런타임 전 초기화로 인한 Spring Bean에서 발생되는 Error을 확인하는게 어려우므로 권장되는 방식은 아님
▶ Error 발생 시 Runtime Exception이 발생.
@Component
class EagerInit{
public EagerInit(){
System.out.println("Eager 초기화");
}
}
@Component
@Lazy
class LazyInit{
public LazyInit(){
System.out.println("Lazy 초기화");
}
}
@ComponentScan
public class LazyInitialize {
public static void main(String[] args) {
var context = new AnnotationConfigApplicationContext(LazyInitialize.class);
System.out.println("Context 초기화");
context.getBean(LazyInit.class);
}
}

。 어플리케이션이 실행되는 시점에서 EagerInit이 먼저 자동초기화
。이후 Spring Context가 초기화된 후 LazyInit이 호출되는 시점에서 지연초기화가 수행됨
Spring Bean Scope
。Spring Bean은 각각 다른 Scope를 가질 수 있다.
▶ @Scope 어노테이션을 통해 설정이 가능
Singleton : default
@Scope(value= ConfigurableBeanFactory.SCOPE_SINGLETON)
。Spring Context 당 Spring Bean을 1개만 생성
▶ 생성된 Spring Bean을 요청 시 Bean Registry에서 가져와서 제공
。Spring Bean의 기본 Scope로서 Spring Context의 시작과 종료까지 유지되는 가장 넓은범위의 Scope
Prototype
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
。요청마다 Spring Bean을 새로 생성하도록 설정
▶ Spring Context 당 복수의 Context Instance가 존재할 수 있음.
。Prototype 선언 시 Spring은 Spring Bean의 생성 및 의존성 주입만 관여하고 더는 관리하지 않는다.
Request
。 Http Request 시 마다 새로운 Spring Bean을 생성
Session
。세션 마다 새로운 Spring Bean을 생성
▶ 사용자의 HTTP Session(동일 사용자로서 여러번의 Http Request가 하나의 Session에 속할 경우)당 새로운 Spring Bean 생성
Application scope :
。WAS당 하나의 Spring Bean이 할당
Spring Bean의 생성 또는 파괴 시 호출하는 메서드 정의
。@PostConstruct , @PreDestroy
。주로 Spring Bean의 초기화 / Clean up 시 호출하는 메서드에 다음 어노테이션을 정의
@PostConstruct :
。Spring Bean 생성 및 의존성 주입이 완료된 직후 자동으로 호출할 Spring Bean의 초기화 메서드에 선언하는 어노테이션
▶ @PostConstruct가 선언된 메서드는 Spring Bean을 참조하기 전에 먼저 호출
。초기화 메서드는 주로 Spring Bean의 resource, default value, logging 을 설정하는 코드를 작성
@PreDestroy :
。Spring Context에서 Spring Bean을 파괴하기전 자동으로 호출할 cleanup method에 선언하는 어노테이션
。cleanup method는 Spring Context가 보유하고 있는 Resource를 해제하는 용도로 사용
▶ Spring Bean이 삭제되기 전 @PreDestory로 선언된 cleanup method를 수행하여 활성화된 연결들을 모두 닫아야한다.
cleanup 메서드는 주로 Spring Bean의 DB Connection 해제 , Resource 해제하는 코드를 작성
@Component
class EagerInit{
public EagerInit(){
System.out.println("Spring Bean 초기화");
}
@PostConstruct
public void init(){
System.out.println("Init 메서드 호출");
}
@PreDestroy
public void cleanUp(){
System.out.println("CleanUp 메서드 호출");
}
}
@ComponentScan
public class InitandDestroy {
public static void main(String[] args) {
var context = new AnnotationConfigApplicationContext(InitandDestroy.class);
System.out.println("Context 초기화");
context.close();
}
}

。Eager Initialization으로 Application 실행 직후 Spring Bean 생성 직후 @PostConstruct 메서드 호출
。Spring Context에 등록된 후 Spring Context가 종료하기 이전 @PreDestroy 메서드를 호출 후 Spring Bean이 파괴