ApplicationContext
- ApplicationContext 인터페이스를 스프링 컨테이너라고 하며, 스프링 컨테이너는 애플리케이션 컴포넌트(Bean)들을 생성하고 관리한다.
- BeanDefinition은 빈 설정 메타정보로, AppConfig의 @Bean 당 각각 하나씩 메타정보를 생성한다.
- 이후 스프링 컨테이너는 생성된 메타정보를 기반으로 스프링 빈을 생성한다.
AppConfig
- 스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정 정보로 사용하여 @Bean이 적힌 메서드를 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록하고, 설정정보를 이용해서 의존관계를 주입한다.
@Configuration
public class ServiceConfiguration {
@Bean
public InventoryService inventoryService() {
return new InventoryService;
}
@Bean
public ProductService productService() {
return new ProductService;
}
}
@Configuration
- @Configuration 어노테이션은 각 빈을 스프링 애플리케이션 컨텍스트에 제공하는 구성 클래스라는 것을 스프링에게 알려준다.
- 더 정확히는 @Configuration을 붙이면 바이트 코드를 조작하는 CGLIB 기술을 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록하는데 이러한 임의의 다른 클래스가 싱글톤을 보장해준다.
- @Bean이 붙은 메서드마다 이미 스프링 빈이 존재하면 존재하는 빈을 반환하고, 없으면 생성해서 스프링 빈으로 등록한 후 반환하는 코드가 동적으로 만들어진다.
- 따라서 @Configuration을 적용하지 않고 @Bean만 사용하면 스프링 빈으로 등록은 되지만 싱글톤을 보장하지 않는다.
스프링 컨테이너 생성
- 스프링 컨테이너를 생성할 때는 구성 정보인 AppConfig.class를 지정해주어야 한다.
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
스프링 빈 등록
- 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록한다.
- 빈 이름은 기본적으로 메서드 이름을 사용하지만, 직접 지정해줄 수도 있다.
- 주의할 점은 빈 이름은 모두 달라야 한다.
컴포넌트 스캔
- @Bean 설정정보가 없어도 자동으로 스프링 빈을 등록하는 기능으로, @Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.
@ComponentScan
- 컴포넌트 스캔을 사용하려면 @ComponentSacn을 설정 정보에 붙여주고, 스프링 빈으로 등록할 클래스에 @Component 어노테이션을 붙여준다.
- 참고로 @Configuration 어노테이션은 @Component 어노테이션을 포함하므로, AppConfig도 스프링 빈으로 등록된다.
@Configuration
@ComponentScan(excludeFilters = @Filter(type = FilterType.ANNOTATION,
classes = Configuration.class))
public class AppConfig {
}
@Autowired
- 생성자에 @Autowired를 지정하면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 의존관계를 주입해준다.
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
탐색 위치
- 모든 자바 클래스를 다 컴포넌트 스캔하면 시간이 오래 걸리기 때문에 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있다.
- 시작 위치로 지정한 패키지를 포함해서 하위 패키지를 모두 탐색하며, 여러 개도 지정할 수 있다.
- 만약 따로 시작 위치를 지정하지 않으면 @ComponentScan이 붙은 설정정보 클래스의 패키지가 시작 위치가 된다.
기본 스캔 대상
- 아래 어노테이션이 지정된 클래스는 컴포넌트 스캔의 기본 대상이 된다.
@Component | 컴포넌트 스캔에서 사용 |
@Controller | 스프링 MVC 컨트롤러로 인식 |
@Service | 스프링 비즈니스 로직에서 사용 |
@Repository | 스프링 데이터 접근 계층에서 사용하며, 데이터 계층의 예외를 스프링 예외로 변환해준다. |
@Configuration | 스프링 설정 정보에서 사용하며, 스프링 빈이 싱글톤을 유지하도록 추가 처리 |
수동 빈 등록
- 애플리케이션에 광범위하게 영향을 미치는 기술 지원 빈은 수동으로 등록해서 설정 정보에 명확하게 나타내는 것이 유지보수에 좋다.
- 기술 지원 빈: 기술적인 문제나 공통 관심사(AOP)를 처리할 때 사용되며, 데이터베이스 연결이나 공통 로그 처리처럼 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들
- 업무 로직 빈: 웹을 지원하는 컨트롤러, 핵심 비즈니스 로직이 있는 서비스, 데이터 계층의 로직을 처리하는 리포지토리 등으로 보통 비즈니스 요구사항을 개발할 때 추가되거나 변경된다.
- 비즈니스 로직 중에서 다형성을 적극 활용하는 경우 수동 빈으로 등록하거나, 자동으로 등록하려면 특정 패키지에 같이 묶어두는 것이 좋다.
'Spring > Spring' 카테고리의 다른 글
빈 생명주기와 콜백 (0) | 2022.03.03 |
---|---|
의존관계 주입 방법 (0) | 2022.03.03 |
객체지향 설계와 스프링 (0) | 2022.02.28 |
@Bean과 @Component (0) | 2022.01.27 |
Gradle 스프링 초기 설정 (0) | 2022.01.20 |