IoC 컨테이너가 관리하는 객체를 '빈(Bean)'이라고 한다.
예를 들어 아래와 같이 new 키워드로 객체를 생성했다고 했을 때 이 인스턴스는 Bean이 아니다.
OwnerController ownerController = new OwnerController();
하지만 같은 ownerController 이지만 아래는 스프링 Bean이라 한다.
applicationContext가 관리하는 객체에서 가져온 것이기 때문이다.
ApplicationContext applicationContext;
@Test
public void getBean(){
OwnerController bean = applicationContext.getBean(OwnerController.class);
assertThat(bean).isNotNull();
}
어떻게 스프링 컨테이너 안에다가 이 빈을 만들어줄까?
아래 두 가지 방법으로 Bean을 설정하게 된다.
1. Component Scanning
- @Component
- @Repository
- @Service
- @Controller
- @Configuration
@Controller
class OwnerController {
...
}
위의 @Controller 라는 애너테이션이 사실 @Component라는 메타 애노테이션을 사용하는 것이다.
따라서 @Component 애노테이션이라 볼 수 있다.
스프링 IoC 컨테이너가 사용하는 인터페이스들이 있는데 이런 인터페이스들을 라이프 사이클 콜백이라 한다.
@Component가 붙어있는 모든 클래스들을 찾아서 해당 클래스들의 인스턴스를 만들어서 Bean으로 등록하는 과정이 이루어진다. 이 복잡한 과정을 담당하는 애너테이션 프로세서 처리기가 아래와 같이 @SpringBootApplication 애너테이션을 보자.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PetClinicApplication {
public static void main(String[] args) {
SpringApplication.run(PetClinicApplication.class, args);
}
}
이 @SpringBootApplication 애너테이션을 들여다보면(위의 PetClinicApplication 클래스에서 마우스를 @SpringBootApplication에 올리고 ctrl+클릭)
@ComponentScan 애너테이션이 있다.
이 애너테이션은 어디서부터 어디까지 Component를 찾아보라고 지시하는 역할을 한다.
@ComponentScan이 붙어있는 위치 즉, @SpringBootApplication 위치에서부터 모든 하위 패키지의 모든 클래스를 탐색하게 된다.
모든 클래스들을 훑어보면서 @Controller 또는 @Component, @Repository 등 애너테이션이 붙어있으면 모두 Bean으로 등록해주는 게 컴포넌트 스캔이라는 기능이다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
그래서 우리가 위의 OwnerController를 직접 Bean으로 등록하지 않더라도 @Controller 애너테이션 덕분에 스프링이 알아서 IoC 컨테이너가 만들어질 때 Bean으로 자동 등록해준다.
예제 프로젝트 PetClinic 에서 Repository(특정 인터페이스)를 상속받은 클래스는 애너테이션 없이도 Bean으로 등록되는데, 스프링 데이터 JPA가 제공해주는 기능에 의해서 자동으로 Bean으로 등록된다.
2. 직접 XML이나 자바 설정 파일에 빈 등록
아래와 같이 자동으로 Bean으로 등록할 수 있게 @Controller 애너테이션을 붙인다.
import org.springframework.stereotype.Controller;
@Controller
public class SampleController {
...
}
아래는 applicationContext에 SampleController가 Bean으로 등록되어 있는지 확인하는 Test 코드이다.
SampleController를 Component 스캔을 통해서 Bean으로 등록한 것이고, 직접 Bean으로 등록하는 것으로 변경해보자.
@Autowired 애너테이션을 사용하면 IoC 컨테이너에 있는 Bean을 주입받아서 사용할 수 있다. (가장 많이 사용함)
@RunWith(SpringRunner.class)
@SPinrgBootTest
public class SampleControllerTest {
@Autowired
ApplicationContext applicationContext;
@Test
public void testDI() {
SampleController bean = applicationContext.getBean(SampleController.class);
assertThat(bean).isNotNull();
}
}
이와 같이 Bean을 직접 등록할 수 있다.
sampleController() 메서드에서 반환하는 객체 자체가 IoC 컨테이너 안에 Bean으로 등록된다.
@Configuration
public class SampleConfig {
@Bean
public SampleController sampleController() {
return new SampleController();
}
}
그렇기 때문에 더이상 SampleController에 @Controller 애너테이션을 붙일 필요가 없다.
// @Controller
class SampleController {
...
}
'WEB > SPRING' 카테고리의 다른 글
Springboot에서 java-email 활용하기 (0) | 2022.11.21 |
---|---|
[Spring] AOP 프로그래밍 (0) | 2022.06.03 |
[Spring] 컴포넌트 스캔 (0) | 2022.06.03 |
[Spring] @Configuration 설정 클래스의 @Bean 설정과 싱글톤 (0) | 2022.06.03 |
[Spring] Inversion of Control (0) | 2022.06.03 |
댓글