Spring Boot
어노테이션 생성해서 Bean 컨테이너 생성 자체 관리하기
SH.DevBlog
2024. 1. 10. 18:39
# 어노테이션 생성
- 어노테이션은 아래와 같이 생성하면 된다.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE , ElementType.METHOD})
@Import(ImportsBeanSelector.class)
public @interface EnableBizHelper {
}
# Retention (어노테이션의 생명주기를 담당)
- RetentionPolicy.SOURCE
- 소스 코드(.java)까지 남아있는다.
- 컴파일해서 .java -> .class 로 변경되면 .class에서는 해당 어노테이션이 사라지고 어노테이션에 해당하는 소스가 생성 될 것이다.(예시 : @Getter)
- RetentionPolicy.CLASS
- 클래스 파일(.class)까지 유지된다.(=바이트 코드)
- 런타임 시에는 어노테이션이 사라진다. (예시 : @NonNull)
- RetentionPolicy.RUNTIME
- 런타임까지 유지된다. (계속 유지되는 것을 의미함)
# Import
- 특정 클레스를 import할 때 사용하는 어노테이션(스프링 진영에서 제공해줌)
# 소스 구성
- 'DeferredImportSelector'는 모든 @Configuration 빈이 처리된 후에 실행되는 클레스로써 특정 조건에 따라 Bean Container로 관리해야 하는 경우에 유용하게 활용할 수 있는 인터페이스이다.
- 사용한 소스는 아래와 같다.
public class ImportsBeanSelector implements DeferredImportSelector {
private final ClassLoader classLoader ;
public ImportsBeanSelector(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
Map<String , Object> methodM = importingClassMetadata.getAnnotationAttributes(EnableBizHelper.class.getName()) ;
ImportCandidates importCandidates = ImportCandidates.load(EnableBizHelper.class, classLoader) ;
List<String> autoConfigs = new ArrayList<>() ;
for(String candidate : importCandidates) {
autoConfigs.add(candidate) ;
}
return autoConfigs.stream().toArray(String[]::new) ;
}
}
- ImportCandidates.load 메소드를 들어가보면 아래와 같은 소스가 있는데, 하단의 프로젝트 경로와 같이 구성하면 해당 패키지 경로에 있는 Class 파일을 읽어와 스프링 Bean으로 등록할 수 있다.
public final class ImportCandidates implements Iterable<String> {
private static final String LOCATION = "META-INF/spring/%s.imports";