Spring Boot 자동 구성에 주석 대신 spring.factories를 사용하는 이유는 무엇입니까?
문서에는 다음과 같이 기술되어 있습니다.
자동 구성 개발 및 조건 사용
공유 라이브러리를 개발하는 회사에서 작업하거나 오픈 소스 또는 상용 라이브러리에서 작업하는 경우 자체 자동 구성을 개발할 수 있습니다.자동 구성 클래스는 외부 jar에 번들할 수 있지만 Spring Boot에서 픽업할 수 있습니다.
다른 모든 것에 대한 주석이 있는 경우(@AutoConfigureAfter 또는 @AutoConfigureBefore 주석도 있음),
주석이 있는 클래스를 가리키도록 속성 파일을 유지하는 이유는 무엇입니까?
프로젝트에 어떤 자동 구성 클래스가 존재하는지 확인하기 위해 전 세계를 스캔하는 것은 아니기 때문입니다.우선, 자동 설정은 일반적인 설정일 뿐입니다.@Configuration
학급.
Spring 컴포넌트를 찾는 방법은 명시적 선언 또는 컴포넌트 스캔을 사용하는 것이지만 컨텍스트를 실제로 시작하기 전에 자동 구성 클래스 목록을 알아야 합니다.
SpringBoot 앱이 시작되면 jars 내의 모든 클래스가 스캔되지 않으므로 SpringBoot 스타터에서는 자동으로 구성할 클래스를 지정해야 합니다.예를 들어 spring-boot-2.0.4 입니다.릴리즈는 다음과 같이 초기화됩니다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
//1. method run will call the construtor below
SpringApplication.run(MyApplication.class, args);
}
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = deduceWebApplicationType();
//2. find all the classes whose key is ApplicationContextInitializer in spring.factories and initialize them
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
...
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
//3. use current thread classcloader to load resources in the classpath
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
//SpringFactoriesLoader.java
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
// 3.1 first find the configuration file
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
...
try {
Enumeration<URL> urls = (classLoader != null ?
// public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
//4. spring.factories file is defined here
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
...
}
spring.disc의 모든 엔트리는 다음 방법으로 로드됩니다.
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelector#loadFactoryNames
protected Collection<String> loadFactoryNames(Class<?> source) {
return SpringFactoriesLoader.loadFactoryNames(source, getClass().getClassLoader());
}
Spring Factories로더는 스프링 코어 라이브러리에 속합니다.아래 스크린샷 참조
- 컴파일 시 정적 후보 목록을 생성하여 스타트업 성능을 향상시킵니다.정적 'spring.factories' 파일을 스캔하기만 하면 됩니다.많은 클래스 파일을 항아리에 스캔하지 않아도 됩니다.springframework 5.0의 @indexed와 비슷합니다.--
META-INF/spring.components
. - 일원화된 구성 관리, 간결하고 호환성이 있습니다.
언급URL : https://stackoverflow.com/questions/32107610/why-use-spring-factories-for-spring-boot-auto-configuration-instead-of-annotatio
'itsource' 카테고리의 다른 글
Angular에서의 조건부 논리JS 템플릿 (0) | 2023.03.13 |
---|---|
Wordpress 플러그인을 통해 스타일시트 로드 (0) | 2023.03.13 |
MUI의 CSS 자 선택기 (0) | 2023.03.13 |
사물을 비스듬히 복사하고 있습니까? (0) | 2023.03.13 |
Amazon Cloudwatch Logs Insights with JSON 필드 (0) | 2023.03.13 |