4.@Component와 컴포넌트스캔

@Component와 컴포넌트스캔

@ComponentScan

SpringBootApplication이 @ComponentScan을 갖고있는데 @ComponentScan으로 인해 @Service @Repository @Controller @Configuration를 붙이면 빈으로 등록되게 해준것이다.
(@Service/ @Repository/ @Controller/ @Configuration 은 내부적으로 @Component 를 갖고있다)

ComponentScan은 basePackagesClasses로 값을 주면 스캔을 해서 빈을 생성하게 된다.

즉 @SpringBootApplication이 어플리케이션 클래스에 붙어있을 경우 해당패키지에 대해 컴포넌트 스캔을 하게된다.(타 패키지는 스캔을 하지않음)

컴포넌트 스캔을 한다고 해서 모든것을 빈으로 생성해주진 않는다. @Filter 으로 원하지 않는것에 대해 거를 수 있다.

빈 주입이 잘안될땐 컴포넌트 스캔의 범위를 잘 생각해보자

요약하면 @Component스캔은 basePackagesClasses / @Filter 만 기억하자!

빈이 많을경우 어플리케이션을 실행할 때 구동시간이 오래걸릴 수 있다.

구동시간이 오래걸려서 싫을 때는 펑션을 사용한 빈 등록을 고려해보자(Spring 5부터 지원)

펑션을 사용한 빈 등록

1
2
3
4
5
6
7
8
MyBean 클래스는 @ComponentScan의 basePackagesClasses 범위 밖이다. MyBean은 @Service 없어도 됨.

public static void main(String[] args) {
new SpringApplicationBuilder().sources(Demospring51Application.class)
.initializers((ApplicationContextInitializer<GenericApplicationContext>)applicationContext -> {
applicationContext.registerBean(MyBean.class);
}).run(args);
}

위를 할경우 빈을 생성할 때 자신의 코드를 추가할 수 있고 구동시간의 이점이 있다.

ComponentScan의 동작 원리

BeanPostProcessor이 아닌 BeanFactoryPostProcessor를 구현한 ConfigurationClassPostProcessor와 연결되어 있다.
BeanFactoryPostProcessor은 BeanPostProcessor와 비슷한데 실행되는 시점이 다름. 다른 모든 빈들이 만들어지기 전에 적용해준다.
다른빈들이 모두 등록되기전에 컴포넌트 스캔을 해서 빈을 등록해준다.
여기서 다른빈이란 펑션을 사용한 빈 등록 등등…

참고사항

펑션을 사용한 빈등록, @Bean 을 통해 빈을 등록하는 방법은 @ComponentScan을 나오게한 원인(많은 빈을 수동으로 등록하는 불편함)을 다시 야기하므로
@ComponentScan외의 것들을 사용하여 빈을 등록할 때는 잘생각해보자.

Share