itsource

Spring Boot 자동 구성에 주석 대신 spring.factories를 사용하는 이유는 무엇입니까?

mycopycode 2023. 3. 13. 20:29
반응형

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로더는 스프링 코어 라이브러리에 속합니다.아래 스크린샷 참조

여기에 이미지 설명 입력

  1. 컴파일 시 정적 후보 목록을 생성하여 스타트업 성능을 향상시킵니다.정적 'spring.factories' 파일을 스캔하기만 하면 됩니다.많은 클래스 파일을 항아리에 스캔하지 않아도 됩니다.springframework 5.0의 @indexed와 비슷합니다.--META-INF/spring.components.
  2. 일원화된 구성 관리, 간결하고 호환성이 있습니다.

언급URL : https://stackoverflow.com/questions/32107610/why-use-spring-factories-for-spring-boot-auto-configuration-instead-of-annotatio

반응형