SpringBoot 학습 (3) - SpringBoot 핵심 의 Spring Boot 자동 설정 원리

Spring Boot 는 SpringApplication 대상 을 예화 할 때 META - INF / spring. factories 파일 을 불 러 오고 이 프로필 의 설정 을 Spring 용기 에 불 러 와 자동 으로 설정 합 니 다.
1. 소스 코드 분석
1. 먼저 Spring Boot 프로젝트 코드 SpringApplication. run (App. class, args) 을 시작 하 는 소스 코드 에 들 어 갑 니 다.
                              프로그램 목록: org / springframework / boot / SpringApplication. java
public static ConfigurableApplicationContext run (Object[ ] sources,String[ ] args ){
    return new SpringApplication( sources ).run( args ) ;
}

2. run 방법 이 실제로 SpringApplication 대상 인 스 턴 스 를 만 드 는 것 을 볼 수 있 습 니 다. 다음은 SpringApplication 대상 인 스 턴 스 를 만 드 는 코드 를 보 겠 습 니 다.
                  프로그램 목록: org / springframework / boot / SpringApplication. java
public SpringApplication( Object... sources ){
    initialize( sources ) ;
}

3. 다음은 initialize (sources) 방법 을 호출 하 는 것 입 니 다. 이 방법의 소스 코드 는 다음 과 같 습 니 다.
                               프로그램 목록: org / springframework / boot / SpringApplication. java
private void initialize(Object[] sources) {
     if (sources != null && sources.length > 0) {
         this.sources.addAll(Arrays.asList(sources));
     }
     this.webEnvironment = deduceWebEnvironment();
     setInitializers((Collection) getSpringFactoriesInstances(
     ApplicationContextInitializer.class));
     setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
     this.mainApplicationClass = deduceMainApplicationClass();
}

initialize (sources) 방법 해석:
  • sources 가 0 이면 SpringApplication sources 에 있 는 sources 에서 이 sources 는 12032 개의 링크 드 HashSet 입 니 다.
  • 스토리 보드 deduce WebEnvironment ⽅ 법 으로 웹 환경 여 부 를 판단
  • initializers 를 설정 합 니 다.
  • Listeners 설정
  • mainApplicationClass 를 설정 합 니 다.
  • 4. initialize 방법 이 호출 되 었 습 니 다. getSpringFactories Instances 방법, 코드 는 다음 과 같 습 니 다.
                                   프로그램 목록: org / springframework / boot / SpringApplication. java
    private  Collection extends T> getSpringFactoriesInstances(Class type,
         Class>[] parameterTypes, Object... args) {
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
         // Use names and ensure unique to protect against duplicates
         //   Set  names       
         Set names = new LinkedHashSet(
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));
         //   names      
         List instances = createSpringFactoriesInstances(type, parameterTypes,
         classLoader, args, names);
         //        
         AnnotationAwareOrderComparator.sort(instances);
         return instances;
    }

    getSpringFactories Instances 방법 분석:
  • ClassLoader 를 먼저 획득 합 니 다.
  • 조 SpringFactories Loader \ # loadFactory Names 를 넣 고 불 러 온 다음 에 LinkedHashSet 에 넣 고 무 게 를 제거 합 니 다.
  • 조 createSpringFactories 인 스 턴 스 초기 화
  • 정렬
  • 5. 있다 getSpringFactories Instances 에서 loadFactory Names 방법 을 호출 하여 이 방법 에 계속 들 어 갑 니 다. 원본 코드 를 보 려 면 다음 과 같 습 니 다.                         
                                     프로그램 목록: org / springframework / boot / SpringApplication. java
    public static List loadFactoryNames(Class> factoryClass, ClassLoader classLoader) {
     String factoryClassName = factoryClass.getName();
     try {
     Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURC
    E_LOCATION) :
     ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
     List result = new ArrayList();
     while (urls.hasMoreElements()) {
     URL url = urls.nextElement();
     Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
     String factoryClassNames = properties.getProperty(factoryClassName);
     result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassN
    ames)));
     }
     return result;
     }
     catch (IOException ex) {
     throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
     "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
     }
    }

    loadFactory Names 방법 분석:
  • factory ClassName 획득, 현재 factory ClassName = org. springframework. context. ApplicationContextInitializer.
  • 전송 되 는 classLoader 를 통 해 META - INF / spring. factories * 12098 건 을 불 러 옵 니 다.
  • 스토리 보드 Properties LoaderUtils \ # loadProperties 를 통 해 Properties 로 전환 합 니 다.
  • factory ClassName 에 대응 하 는 값 을 되 돌려 줍 니 다. 현재 로 서 는 spring - boot - starter - web 에 만 의존 하기 때문에 다음 설정 을 불 러 옵 니 다.
  • spring - boot / META - INF / spring. factories 에서. org. springframework. context. applicationContextInitializer 값
  • 6. 상기 소스 코드 에서 선반 을 볼 수 있 습 니 다. 상수: FACTORIESRESOURCE_LOCATION, 이 상수 의 소스 코드 는 다음 과 같 습 니 다.
    /**
    *The location to look for factories.
    *

    Can be present in multiple JAR files. */ public static final String FACTORIES_RESOURCE_LOCATION="META-INF/spring.factories";


    이 소스 코드 에서 알 수 있 듯 이 최종 Spring Boot 는 META - INF / spring. factories 파일 을 불 러 와 자동 으로 설 정 됩 니 다.그 위 치 는 다음 그림 과 같다.
     
    2. spring. factories 분석
    spring factories 파일 은 매우 중요 합 니 다. Spring Boot 에서 제 정 된 자동 설정 파일 을 찾 도록 지도 합 니 다.
    spring factories 파일 의 중점 내용 분석 은 다음 과 같다.
    # PropertySource Loaders
    org.springframework.boot.env.PropertySourceLoader=\
    org.springframework.boot.env.PropertiesPropertySourceLoader,\
    org.springframework.boot.env.YamlPropertySourceLoader

    org. springframework. boot. env. Property SourceLoader 에 대응 하 는 값 은 지정 한 Spring Boot 설정 파일 이 지원 하 는 형식 을 표시 합 니 다.Spring Boot 의 설정 파일 에는 properties, xml, yml, Yml 몇 가지 형식 을 지원 합 니 다.그 중에서 properties 와 xml 에 대응 하 는 Loader 류 는 Properties Property SourceLoader 이 고 yml 과 Yml 에 대응 하 는 Loader 류 는 YamlProperty SourceLoader 입 니 다.
    #Run Listeners
    org.springframework.boot.SpringApplicationRunListener=\
    org.springframework.boot.context.event.EventPublishingRunListener

    org. springframework. boot. SpringApplicationRunListener 에 대응 하 는 값 은 실행 중인 모니터 클래스 를 표시 합 니 다.기본적으로 EventPublishingRunListener 를 불 러 옵 니 다. 이 RunListener 는 SpringApplication 대상 의 run 방법 이 서로 다른 단계 로 실 행 될 때 해당 이벤트 가 SpringApplication 대상 의 Listeners 에 기 록 된 이벤트 감청 기 를 발표 합 니 다.
    #Applicaiton Context Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
    org.springframework.boot.context.ContextIdApplicationContextInitializer,\
    org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
    org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

    org. springframework. context. applicationContextInitializer 에 대응 하 는 값 은 Spring Boot 의 응용 프로그램의 초기 화 류 를 표시 합 니 다.기본적으로 응용 프로그램 ContextInitializer 클래스 4 개 를 불 러 옵 니 다.
  • Configuration Warnings Application ContextInitializer 의 역할 은 일반적인 설정 오 류 를 보고 하 는 것 입 니 다.
  • ContextIdApplication ContextIntializer 의 역할 은 Application Context 에 ID 를 설정 하 는 것 이다.
  • Delegating Application ContextIntializer 의 역할 은 초기 화 된 작업 을 context. initializer. classes 환경 변수 가 지정 한 초기 화 기 에 위탁 하 는 것 입 니 다.
  • ServerPortInfoapplicationContextInitializer 는 Emvedd ServletCibtauber - Initialized Event 형식의 이 벤트 를 감청 한 다음 에 내 장 된 웹 서버 가 사용 하 는 포트 를 application - context 에 설정 하 는 역할 을 합 니 다.

  •  
     
    3. Spring Boot 웹 개발 자동 설정
    spring. factories 에서 알 수 있 듯 이 웹 개발 의 자동 설정 클래스 는 org. spring from work. boot. autoconfigure. web. WebMvcAutoConfiguration 입 니 다. 이 클래스 에 서 는 Spring MVC 의 설정 이 자동 으로 실 현 됩 니 다.현재 Spring MVC 의 다음 설정 을 예 로 들 면 Spring Boot 가 이 자동 설정 을 어떻게 실현 하 는 지 알 수 있 습 니 다.
    
        
        
    

    1. WebMvcAutoConfiguration 의 소스 코드 는 다음 과 같 습 니 다.
    @Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
        WebMvcConfigurerAdapter.class })
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration{

    그 중에서 @ ConditionalOnClass 는 조건 설명 입 니 다. 현재 프로젝트 운영 환경 에 Servlet 류 가 있 고 Dispatcher Servlet 류 와 WebMvcConfigurerAdapter 류 가 있 습 니 다. (이 프로젝트 는 Spring MVC 를 통합 해 야 한 다 는 뜻) Spring Boot 는 WebMvcAutoConfiguration 을 초기 화하 여 자동 으로 설정 할 수 있 습 니 다.
    2. 보기 해상도 기 를 자동 으로 설정 합 니 다 ViewResolver:
    WebMvcAutoConfiguration 클래스 에서 다음 소스 코드 를 찾 습 니 다.
    @Bean
    @ConditionalOnMissingBean
    public InternalResourceViewResolver defaultViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix(this.mvcProperties.getView().getPrefix());
        resolver.setSuffix(this.mvcProperties.getView().getSuffix());
        return resolver;
    }

    @ Bean 은 여기 서 Bean 대상 인 Internal ResourceView Resolver 를 정 의 했 습 니 다. 예전 에는 메모 로 정 의 했 습 니 다.
    @ conditional OnMissingBean 은 조건 설명 입 니 다. 현재 환경 에서 이 Bean 이 없 을 때 만 이 Bean 을 만 듭 니 다.
    방법 은 반환 값 인 Internal ResourceView Resolver 입 니 다. 바로 우리 가 필요 로 하 는 대상 입 니 다. 보기 해석 기 에 있 는 접두사 와 접두사 Spring Boot 는 어떻게 자동 설정 을 실현 합 니까?
    resolver.setPrefix(this.mvcProperties.getView().getPrefix());
    resolver.setSuffix(this.mvcProperties.getView().getSuffix());

    이 원본 코드 는 View 대상 을 찾 을 수 있 습 니 다.
    public static class view{
        
        /**
        * Spring MVC     
        */
        private String prefix;
    
        /**
        * Spring MVC     
        */
        private String suffix;
        
        public String getPrefix(){
            return this.prefix;
        }
        public void setPrefix(String prefix){
            this.prefix = prefix;
        }
        public String getSuffix(){
            return this.suffix;
        }
        public void setSuffix(String suffix){
            this.suffix = suffix;
        }
    
    }

    View 대상 은 prefix, suffix 를 통 해 보기 해석 기 에 필요 한 접두사 와 접 두 사 를 불 러 옵 니 다. 이 매개 변 수 는 전역 설정 파일 을 통 해 접두사 와 접 두 사 를 지정 할 수 있 습 니 다. 설정 은 다음 과 같 습 니 다.
    spring.mvc.view.prefix = # Spring MVC view prefix
    spring.mvc.view.suffix = # Spring MVC view suffix

    좋은 웹페이지 즐겨찾기