본문 바로가기

Spring/Spring

(SPRING) IoC 컨테이너 - @Component와 컴포넌트 스캔

@SpringBootApplication 내부

@SpringBootApplication에 있는 @ComponentScan

@ComponentScan 내부

 

 

basePackages의 값이 문자열이기 때문에

type safe 하지 않다.

 

 

 

 

type safe 한 방법으로 설정 가능한 basePackagesClassses

 


스캔의 범위 지정

 

스캔의 시작 지점

@SpringBootApplication
public class Demospring51Application {

	public static void main(String[] args) {
		SpringApplication.run(Demospring51Application.class, args);
	}
}

@ComponentScan을 붙이고 있는 configuration부터 모두 스캔을 시작한다.

하지만 패키지가 다를 경우 스캔을 하지 않는다.

 

스캔의 범위를

지정해준다.

 

 

 

 

 

 

 

 

bean으로 등록되지 않았기 때문에 @Autowired를 

받을 수 없는 것이다.

 

 

 

 

필터 : 어떤 애노테이션을 스캔할지 또는 하지 않을지

@Component   
  @Repository 
  @Service 
  @Controller  
  @Configuration

단점 :

싱글턴 scope의 Bean들은 처음에 빈을 생성하기 때문에 등록해야 할 Bean이 많을 경우 초기 구동 시간이 오래 걸린다.

- 애플리케이션 구동 타임에 딱 한 번만 느리다.

 

구동 시간에 예민하다면?

 

펑션을 사용한 빈 등록

 

ApplicationContextInitializer활용

@SpringBootApplication
public class Demospring51Application {

	@Autowired
	MyService myService;


	public static void main(String[] args) {
//		SpringApplication.run(Demospring51Application.class, args);
		var app = new SpringApplication(Demospring51Application.class);
		/*중간에 무엇을 하고 싶을 때*/
		app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> ctx.registerBean(MyService.class));
		/*중간에 무엇을 하고 싶을 때*/
		app.run(args);
	}
}

Supplier추가

	public static void main(String[] args) {
//		SpringApplication.run(Demospring51Application.class, args);
		var app = new SpringApplication(Demospring51Application.class);
		/*중간에 무엇을 하고 싶을 때*/
		app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx ->
		{
			/*추가적인 코딩을 할 수 있다.*/

			/*추가적인 코딩을 할 수 있다.*/
			ctx.registerBean(MyService.class);
			ctx.registerBean(ApplicationRunner.class, () -> args1 -> System.out.println("Functional Bean Definition"));

		});
		/*중간에 무엇을 하고 싶을 때*/
		app.run(args);
	}

동작 원리 

@ComponentScan은 스캔할 패키지와 애노테이션에 대한 정보 

실제 스캐닝은 ConfigurationClassPostProcessor라는 BeanFactoryPostProcessor에 의해 처리됨.

 

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/ConfigurationClassPostProcessor.html

 

ConfigurationClassPostProcessor (Spring Framework 5.2.2.RELEASE API)

Get the order value of this object. Higher values are interpreted as lower priority. As a consequence, the object with the lowest value has the highest priority (somewhat analogous to Servlet load-on-startup values). Same order values will result in arbitr

docs.spring.io

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html

 

BeanFactoryPostProcessor (Spring Framework 5.2.2.RELEASE API)

Factory hook that allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory. Useful for custom config files targeted at system administrators that override bean p

docs.spring.io

다른 빈들을 등록하기 이전에 빈으로 등록하기 이전에 빈으로 등록

 

 

구동 시 무겁다고 해서 모든 것을 펑션을 이용한 빈 등록으로 바꾸어버리면...
코드가 너무 복잡해지며 @Component 등장 이전의 상태로 다시 돌아가 버리는 것이 아닐까?
하나의 빈을 추가적으로 등록 해야하는 경우와 같은 예외적인 상황에만 
적용하는 것이 좋을 것 같다.

코드 참조

https://github.com/mike6321/Spring/tree/master/Spring/demospring51

 

mike6321/Spring

Contribute to mike6321/Spring development by creating an account on GitHub.

github.com