스프링 컨테이너는 스프링에서 자바 객체들을 관리하는 공간을 말합니다. 자바 객체를 스프링에선 빈(Bean)이라고 하는데, 스프링 컨테이너에서는 이 빈의 생성부터 소멸까지를 개발자 대신 관리해주는 곳이라고 할 수 있습니다.
컨테이너는 크게 두 종류로 나눌 수 있습니다. 하나는 BeanFactory
이고, 다른 하나는 ApplicationContext
입니다. ApplicationContext
컨테이너가 BeanFactory
의 기능을 포괄하면서 추가적인 기능을 제공하기 때문에 대부분의 경우에는 ApplicationContext
를 사용합니다.
그렇다면 어떤 부분이 ApplicationContext
에 추가가 되었을까요? 이벤트 발행 및 구독 모델 지원 및 리소스 조회 편의성 제공, 환경변수를 구분해주는 기능 및 언어 국제화를 지원합니다.
스프링 컨테이너에 객체, 빈을 등록하는 이유는 스프링이 각 객체간 의존관계를 관리하도록 하는데에 큰 목적이 있습니다. 객체가 의존관계를 등록할 때는 스프링 컨테이너에서 해당하는 빈을 찾고, 그 빈과 의존성을 만듭니다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
@Service
public class MemberService {
private final MemberRepository memberRepository;
...
}
위의 코드와 같이 MemberController
클래스에는 @Controller
Annotation을, 그리고 생성자에 @Autowired
를 적어두면, 이 인스턴스는 MemberService
와 의존관계를 가진다는 의미를 줍니다.
단, @Autowired
가 정상적으로 동작하려면 두 인스턴스가 빈으로써 스프링 컨테이너에 들어가있어야 합니다.
ApplicationContext
의 구현체로는 AnnotationConfigApplicationContext()
가 있습니다. AnnotationConfigApplicationContext
의 매개변수에 구성정보로 AppConfig.class
와 같은 Bean을 정의한 @Configuration
클래스를 넣어주면 됩니다.
스프링은 보통의 경우 스프링 컨테이너에 빈 인스턴스를 단 한개만 저장하는 싱글톤 방식을 채택하고 있습니다. 빈 이름은 항상 다르게 지정이 되어야 합니다. 예상치 못한 여러 오류가 발생하는데, 이를 개발 중 발견하기 매우 어렵기 때문입니다. 스프링 빈을 등록하는 방법은 크게 2가지로 나뉩니다.
컴포넌트 스캔
@Component
Annotation을 통해 가능한데, 이 외에도 스프링 프레임워크에서 제공하는 @Controller
나 @Service
혹은 @Repository
와 같은 Annotation은 아래와 같이 인터페이스로 @Component
Annotation을 받기 때문에 컴포넌트 등록이 가능합니다.
...
@Component
public @interface Service {
...
}
단, 실행되는 패키지와 같은 패키지에 있는 클래스에 대해서만 @Component
Annotation이 적용됩니다.
스프링 빈 직접 등록
스프링 빈을 직접 등록하는 것은 @Configuration
과 @Bean
Annotation으로 가능합니다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
}
ApplicationContext
타입의 변수를 ac
라고 가정하고 ac.메서드명
형태로 아래 메서드들을 사용해야 합니다.
getBeanDefinitionNames()
스프링에 등록된 모든 빈 이름을 조회합니다.
getBean()
특정 스프링빈을 조회하는데 사용됩니다. 매개변수로 여러 종류가 올 수 있습니다. Srping 문서
조회하고자 하는 빈이 존재하지 않으면 NoSuchBeanDefinitionException
예외가 발생합니다.
BeanDefinition.getRole()
빈의 역할을 출력한다. 빈의 역할은 크게 두가지로 나뉩니다. 하나는 스프링이 내부의 동작을 위해 사용하는ROLE_INFRASTRUCTURE
, 다른 하나는 사용자가 정의한 빈인ROLE_APPLICATION
입니다.
getBeansOfType()
해당 타입에 해당하는 모든 빈을 조회할 수 있습니다.