leelee.log

[Spring] @SpringBootApplication과 @ComponentScan 본문

개발/Backend

[Spring] @SpringBootApplication과 @ComponentScan

leeleelee3264 2020. 3. 17. 23:06

spring framework

 

 

 Spring에서 프로젝트를 구동하기 위해서 제일 처음으로 실행되는 class는 @SpringBootApplication이라는 어노테이션이 붙어있는 class이다. 여기서 모든 것이 시작 되었다고 말 할 수 있다. 그럼 @SpringBootApplication에 뭐가 들어있을까?

 

 점점 공부를 하면서 드는 생각이지만 Spring에서 제일 중요한 개념은 Bean이 아닐까 싶다. @SpringBootApplication이 중요한 이유는 @ComponentScan이라는 어노테이션을 품고 있기 때문이다. @ComponentScan은 Spring에게 어디서부터 어디까지의 @Component 어노테이션이 붙은 class들을 읽어들여 bean을 만들어야 하는지를 알려준다. 여기서 중요한 사실은 기본적으로 세팅이 되는 범위는 @SpringBootApplication class가 들어있는 패키지부터 그 밑의 패키지들 까지 읽는 다는 것이다. 상위패키지인 경우에는 아무리 @Component 를 사용해도 읽어오지 못한다. 패키지 자체를 import해서 prototype 객체처럼 사용이 가능한데 어쨌든 bean은 아니다.

 

class tree

 예를 들어 지금 @SpringBootApplication은 SpringapplicationcontextApplication.java에 들어있는데 highPackage는 SpringApplicationcontextApplication보다 상위에 있기 때문에 spring이 읽어오지 못하고 Bean을 만들지 못한다. HighClass에 @Service와 같은 어노테이션을 사용해도 아무런 소용이 없다.

 @SpringBootApplication 속에는 @SpringBootConfiguration이라는 어노테이션이 하나 더 있는데 까보면 결국 @Configuration이다. ComponentScan을 가지고 있는 Configuration이 빈을 만들기 시작한다는데 결국 @SpringBootApplication 안에서 모든게 진행이 된다. @Filter은 bean으로 만들 필요가 없는 class를 선별해두는 기능을 한다.  이건 추가로 들은 설명인데 @ComponentScan이 원래 패키지 단위로 읽어왔기 때문에 scanBasePackages로 읽어왔었다는데 type safe하지가 않아서 scanBasePackageClasses로 읽어온다고 한다.

 

 Spring이 시작할 때 한 번에 사용하는 모든 Bean을 만들어버리기 때문에 서버를 부팅했을 때 초기 구동시간이 좀 길다고 한다. (이때 lazy initailization을 사용할 수 있지 않을까 생각했다) 초기에 잠깐 시간이 걸리고 그 이후로는 빈을 만드는데 시간을 쓰지 않기 때문에 합당하다고 생각하는데 만약 어떤 빈은 따로 생성을 하고 싶거나 하면 functional하게 bean을 생성하는 방법도 있다고 한다. @SpringBootApplication class에서 직접 만들어주는 방법인데 내가 하기에는 너무 복잡하고, @ComponentScan의 장점을 없앨 수 있는 기능이라서 따로 다루지는 않고 있다는 정도로만 하고 넘어가겠다. BeanFactoryPostProcesser를 상속받은 다른 class를 사용해서 ComponentScan으로 만들어지는 Bean보다 빨리 생성이 된다고 한다.

 


@Component를 품고 있는 어노테이션에는 @Controller, @Service, @Repository, @Configuration 이 있다.