Spring

[Spring] 예제로 보는 Classpath Scanning and Managed Components

KEMON 2020. 5. 18. 01:42
728x90

1. @ComponentScan

@Configuration
@ComponentScan(basePackages = "패키지명")
public class AppConfig {

}
@Component
public class B {
}

basePackages에 해당하는 패키지 안의 @Component 어노테이션이 붙은 class를  scanning하고 자동으로 Bean으로 등록시킨다.

즉, 위의 클래스B 는 xml에 Bean으로 등록을 안해도 Bean으로 등록시켜준다.  

(단, AppConfig 이 클래스는 xml에 Bean이라고 등록을 해야한다.)

 

2. @Repository 

@Repository
public class JpaMovieFinder implements MovieFinder {
    // implementation elided for clarity
}

자동으로 Bean으로 등록될 Component 중 DAO처럼 사용될 Bean

 

3. @Service

@Service
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

Component인데 비지니스 로직을 담당하는 Bean에 사용 

※@Service("name") : @Resource(name = "name")으로 호출 가능

4. @Controller는 Spring MVC편에서 정리

5.  Using Filters to Customize Scanning

Filter Types들은 아래와 같다.

여기 예제에서는 ASSIGNABLE , REGEX  Filter Type을 사용한다.  

출처 : https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-classpath-scanning

@Configuration
//@ComponentScan(basePackageClasses = Main.class, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = B.class))
@ComponentScan(basePackageClasses = Main.class, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX,pattern = "kr.co.fastcampus.cli.B"))
public class Main {

    public static void main(String[] args)  {

        //ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("dao.xml");
        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(Main.class); //class넣는게 실수를 줄여준다.
  
        B b = context.getBean(B.class);
        log.info(""+b);

        context.close();
    }
}

1) @ComponentScan에 excludeFilters 옵션을 넣으면 Filter에 의해 Bean으로 등록되지 않는다.

2) ASSIGNABLE_TYPE : @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = B.classs) 

   => B라는 Class는 제외하고 Bean으로 등록시켜준다.

3) REGEX : @ComponentScan.Filter(type = FilterType.REGEX, pattern = "kr.co.fastcampus.cli.B")

   => B라는 Class(패키지명)는 제외하고 Bean으로 등록시켜준다. 

4) ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(Main.class);

   => ClassPathXmlApplicationContext와 다르게 AnnotationConfigApplicationContext를 사용하면 xml설정 없이 어노테이션만으로 Application 동작이 가능하다. 

 

※ComponentScan의 문제점 

   자바 파일이 많아지면 컴포넌트들이 2개 3개밖에 없는 경우 수 많은 자바를 스캔하며 컴포넌트를 찾게 되는데 이는 속도가 느려지고 매우 불필요한 작업이 된다.

이를 해결하기 위해 dependency에 index를 추가해 주면 된다.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-indexer</artifactId>
        <version>5.2.6.RELEASE</version>
        <optional>true</optional>
    </dependency>
</dependencies>

  주의할 점 : version은 Springframework의 spring-context의 version과 맞춘다.

                   jar war 만들때META-INF/spring.components 만들어지고 파일에 컴포넌트 스캔할 클래스 정보들이 들어간다.

 

728x90