Tools/Spring

Component와 Component Scan

칼쵸쵸 2020. 8. 9. 23:20

Component Scan의 동작원리

스프링 프로젝트의 @SpringBootApplication 어노테이션이 존재하는곳에서 스프링 프로젝트가 시작됨

@SpringBootApplication 내부에는 String[] scanBasePackages() default {} 메서드가 존재하는데 이러한 메서드를 통해 

@SpringBootApplication이 존재하는 클래스가 속해 있는 클래스를 basepackage로 설정된다.

이렇게 basepackage로 등록된 package 내부에서 빈으로 등록될 Component들을 검색한다.

 

@Component 어노테이션을 기본으로

각각의 용도에 따라 @Repository, @Service, @Controller ,@Configuration으로 세분화 할 수 있으며 

위의 4가지 어노테이션들은 @Component를 내부에 가지고 있다.

 

이렇게 동작하는 Component Scan은 초기 구동시 검색 , 등록하며 초기등록시 시간이 소요될 수 있다.

기본적인 Component Scan은 Reflection이나 Proxy를 사용하기 때문에 (ConfigurationClassPostProcessor라는 BeanFactoryPostProcessor을 사용) 구동시간에 성능상 영향을 줄 수 있다.

 

구동시간에 민감하다면 펑션을 활용한 Bean 등록을 수행할 수 있다.

 

펑션을 활용한 Bean 등록

package main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
@SpringBootApplication
public class SpringstudyApplication {
	public static void main(String[] args)
	{
		new SpringApplicationBuilder() 
		.sources(SpringstudyApplication.class)
		.initializers(
				(ApplicationContextInitializer<GenericApplicationContext>) applicationContext ->
				{ 
					applicationContext.registerBean(Repo1.class);
				}
				)
		.run(args);
	} 
}

SpringApplicationBuilder라는 객체를 통해 펑션을 활용하여 빈을 등록 할 수 있다.

SpringApplicationBuilder를 람다식으로 재구현하는 방식으로 SpringApplication 클래스를 등록하고 이때 initializing을 수행하는 동안에 행위를 정의 할 수 있다.

위의 예시는 Repo1을 빈으로 등록하는 기본적인 예시로써 다음과 같이 응용할 수 있다.

 

 

package main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
@SpringBootApplication
public class SpringstudyApplication {
	public static void main(String[] args)
	{
		new SpringApplicationBuilder() 
		.sources(SpringstudyApplication.class)
		.initializers(
				(ApplicationContextInitializer<GenericApplicationContext>) applicationContext ->
				{ 
					System.out.println("Before Register");
					applicationContext.registerBean(Repo1.class);
					System.out.println("After Register");
				}
				)
		.run(args);
	} 
}

 

Repo1 객체가 빈으로 등록되기 전에 Before Register를 출력하고 빈으로 등록된 후에는 After Register를 출력 하게 된다. 이를 통해 Bean 등록을 코드상으로 조작 할 수 있으며 구동시간을 줄여 줄 수 있다.

 

 

 

 

'Tools > Spring' 카테고리의 다른 글

스프링 AOP 적용 예제  (0) 2021.02.28
스프링 AOP 기본 동작 원리  (0) 2021.02.27
ApplicationContext-2 (Autowired)  (0) 2020.08.06
ApplicationContext-1 (Bean을 등록하는 방법)  (0) 2020.08.04
Spring Ioc 컨테이너와 Bean  (0) 2020.08.04