이게 스프링 컨테이너를 의미한다. 이것의 구현체가 AnnotationConfigApplicationContext
@Bean이 붙은 메소드 명을 스프링 빈의 이름으로 사용한다.
xml기반으로 만들 수 있고, 아니면 annotation 기반의 자바 설정 클래스로 만들 수 있다.
스프링 컨테이너의 최상위 인터페이스. (AppicationContext보다 더 상위)
ApplicationContext 인터페이스의 구현체
구성정보를 지정해주어야 한다.
new AnnotationConfigApplicationContext(AppConfig.class);
// 여기서 AppConfig가 구성정보다.
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
Object bean1 = ac.getBean(빈 이름, 타입);
Object bean2 = ac.getBean(타입);
ac.getBeanDefinitionNames();
// 스프링에 등록된 모든 빈 이름을 조회함.
생성 불가능하다.
import문은
import org.springframework.stereotype.~~;
1) @Component
2) @Service
3) @Repository
4) @Controller
5) @Configuration
위 어노테이션이 붙은 모든 클래스를 스프링 빈으로 등록한다.
excludeFilters와 includeFilters로 scan 범위를 조정할 수 있다.
AppConfig를 보면 t가 요청할 때마다 매번 객체를 새로 생성한다면 성능이 저하될 것이고, 오류 가능성도 오를 것이다.
따라서 인스턴스를 1개만 생성해서 공유하는 방식으로 작동한다.
1) DIP 위반
2) OCP 원칙을 위반할 가능성
3) 내가 지정하기 때문에 테스트 난이
4) private 접근제어 때문에 자식 클래스 만들기 어려움
5) 유연성 저하
하지만 스프링에서는 위 문제점을 해결하면서 싱글톤 패턴으로 작동한다.
스프링 컨테이너는 싱글톤 컨테이너 역할을 한다
이에 주의사항으로 무상태로 설계해야 한다는 점이 있다. 상태가 유지될 경우(Client가 값을 변경할 수 있는 field가 존재) 큰 문제가 생길 수 있다.
가급적 읽기만 가능해야 한다.
스프링 빈이 등록될 때 @CGLIB에 의한 객체 (Proxy 객체)가 스프링 컨테이너가 들어간다. 바이트코드 조작 라이브러리로 있으면 기존 Logic, 없으면 새로 생성한다.
(1) 스프링 컨테이너 생성
(2) 스프링 빈 생성 (생성자 주입)
(3) 의존관계 주입 (setter/필드 주입)
(4) 초기화 콜백
(5) 사용
(6) 소멸 전 콜백
(7) 스프링 종료
생성자 레벨에서 구현할 거는 객체 내부의 값 세팅할 때만..! 이 레벨까지만 수행한다.
(1) 인터페이스 이용
이럴 때 쓰는 스프링 전용 인터페이스가 존재하며, 외부 라이브러리는 사용 불가능하다.
(2) 설정정보에 초기화/종료 메소드 지정
@Bean(initMethod = "~~", destroyMethod = "~~")
외부 라이브러리도 적용 가능하다. 하지만 destroyMethod를 내부적으로 보면 (inferred)가 있어서 close, shutdown의 이름이 들어간 함수는 자동으로 실행된다.
(3) @PostConstruct, @PreDestroy 어노테이션 사용
사용할 메소드 위에 해당 어노테이션만 붙이면 된다.
외부 라이브러리에는 적용 불가능하다.
패키지가 javax.~~이므로 스프링이 아닌 다른 컨테이너에도 적용이 가능하다.
스프링 컨테이너는 prototype 빈을 생성
의존관계 주입
반환
하고 끝난다.
이후의 종료는 클라이언트한테 책임이 있다.