javabeans 객체의 life-cycle을 관리하고 의존성을 주입해주는 component
ioc, di 컨테이너
컨테이너는 물리적인 개념이라기 보다 객체 관리의 개념 또는 시스템에 가까움
등록된 빈의 부모 타입으로 조회하면, 자식 타입도 함께 조회됨
별도 설정을 하지 않을 경우 컨테이너는 빈 객체를 싱글톤 범위로 관리
싱글톤을 보장하기 위해 CGLIB라이브러리를 사용해서 설정 클래스를 상속받는 프록시 객체를 생성한 후 등록
BeanFactory
컨테이너의 최상위 인터페이스
빈 생성과 검색에 대한 기능을 정의
생성된 객체를 검색하는 데 필요한 getBean()
빈 객체를 lazy-loading 개념에 따라 필요한 시점에 생성
transaction 관리, aop, 이벤트 처리 등의 고급 기능은 제공하지 않음
ApplicationContext
BeanFactory를 확장해 더 많은 기능을 제공하는 인터페이스
이벤트 시스템, aop, transaction 관리, 국제화(i18n), 프로필/환경 변수 등
모든 빈 객체를 eager-loading 개념에 따라 미리 생성하여 앱 시작 시점에 로드
AnnotationConfigApplicationContext
BeanFactory와 ApplicationContext에 정의된 기능의 구현을 제공하는 클래스
어노테이션을 이용한 클래스로부터 객체 설정 정보를 가져옴
Note
어떤 구현 클래스를 사용하든, 각 구현 클래스는 설정 정보로부터 빈이라고 불리는 객체를 생성하고 그 객체를 내부에 보관한다. 그리고 getBean()를 실행하면 해당하는 빈 객체를 제공한다.
GenericXmlApplicationContext
범용 xml 컨테이너로서 xml로부터 객체 설정 정보를 가져오는 클래스
classpath 경로를 기준으로 xml 설정 파일을 찾는 ClassPathXmlApplicationContext와 전체 파일 시스템 경로를 기준으로 xml 설정 파일을 찾는 FileSystemXmlApplicationContext 역할을 모두 수행 가능
스프링 3부터 권장되는 방식이지만, 현재는 잘 사용되지 않음
BeanDefinition
빈의 메타 정보를 담고 있는 추상화 인터페이스
BeanDefinitionReader의 구현체에 의해 BeanDefinition를 로드하고 등록
최종적으로 BeanFactory가 이를 기반으로 빈을 생성
@Bean
@Configurationpublic class AppConfig { @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } // ...}
설정 클래스 내부의 @Bean 메서드가 반환하는 객체를 컨테이너가 관리하는 빈 객체로 직접 등록
@Bean 메서드의 이름으로 빈 객체를 식별
name 속성을 사용하여 빈 객체의 이름을 바꿀 수 있음
@Component
@Component // memberServiceImpl이라는 이름으로 빈 등록public class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository; // DIP 만족 @Autowired public MemberServiceImpl(MemberRepository memberRepository) { super(); this.memberRepository = memberRepository; // ...}
@ComponentScan의 감지 대상이 되어 빈으로 등록될 수 있도록 표시하는 클래스 레벨 어노테이션
클래스 이름의 첫 글자를 소문자로 변환한 이름이 빈 이름이 됨
value 속성을 지정하면 빈 이름을 명시적으로 설정할 수 있음
@Configuration
어노테이션 기반의 설정 클래스로 인식되도록 하는 어노테이션
CGLIB를 통해 프록시 객체로 생성되어 빈으로 등록됨
@Bean 메서드 간 호출 시에 싱글톤을 보장
proxyBeanMethods 속성 값을 false로 설정할 경우 프록시 생성이 비활성화 됨
한 개 이상의 설정 클래스를 사용할 수 있음
@Controller
스프링 mvc의 컨트롤러로 등록
@Service
서비스 계층 클래스를 컴포넌트로 등록
트랜잭션 처리, aop 적용 등 스프링의 부가 기능을 적용할 수 있는 대상임을 명시적으로 나타냄
@Repository
dao 계층을 컴포넌트로 등록
jdbc의 Exception을 스프링의 DataAccessException으로 자동 변환
내부적으로 PersistenceExceptionTranslationPostProcessor가 처리
public class AutowiredTest { @Test void AutowiredOption() { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestBean.class); } static class TestBean { @Autowired(required = false) public void setNoBean1(Member noBean1) { System.out.println("noBean1: " + noBean1); } @Autowired public void setNoBean2(@Nullable Member noBean2) { System.out.println("noBean2: " + noBean2); // noBean2: null } @Autowired public void setNoBean3(Optional<Member> noBean3) { System.out.println("noBean3: " + noBean3); // Optional.empty } }
}
`@Autowired`를 사용할 때 `@Autowired`의 `required` 속성, `org.springframework.lang.Nullable`, `java.util.Optional`를 이용해서 옵션 처리를 할 수 있다. 주입할 빈이 존재하지 않을 때 `required` 속성을 사용하면 해당 메서드를 호출하지 않지만, `@Nullable`를 사용하면 주입할 빈이 존재하지 않더라도 해당 메서드를 호출하고 `NULL`을 전달한다.