SpringBoot 자동 설정 원리,당신 은 정말 알 고 있 습 니까?알 기 쉽다

개술
위의 블 로그SpringBoot 소개 및 빠 른 구축에서 우 리 는 SpringBoot 가 무엇 인지,그리고 SpringBoot 를 어떻게 사용 하 는 지 간단하게 소 개 했 지만,우 리 는 SpringBoot 의 기본 원리 에 대해 소개 하지 않 았 다.이 블 로그 에서 우 리 는 SpringBoot 가 어떻게 실현 되 는 자동 설정 인지 에 중심 을 두 었 다.
의존 관리
우리 pom 파일 에서 가장 핵심 적 인 의존 도 는 다음 과 같 습 니 다.

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.4</version>
    <relativePath/>
</parent>
부모 프로젝트 의존,모든 의존 버 전 정보 규정:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.4.4</version>
</parent>
이 를 통 해 우 리 는 springboot 프레임 워 크 가 모든 개발 에서 자주 사용 하 는 의존 버 전 번 호 를 거의 밝 혔 고 버 전 번호 에 관심 을 가 질 필요 가 없 으 며 자동 버 전 중재 체 제 를 실현 한 것 을 발견 했다.물론 우 리 는 우리 의 수요 에 따라 기본 적 인 의존 버 전 을 교체 할 수 있다.
핵심 주석@SpringBootApplication

@SpringBootApplication
public class BootApplication {

    public static void main(String[] args) {
        SpringApplication.run(BootApplication.class, args);
    }
}
위의 시작 클래스 에서 우 리 는 낯 선 주해@SpringBootApplication 을 발 견 했 습 니 다.이 주해 의 의 미 는 무엇 입 니까?우리 눌 러 서 들 어가 보 자.

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
사실@SpringBootApplication 은 위의 세 개의 주해 의 조합 체 입 니 다.우 리 는 이 세 개의 주해 에 대해 명확 하 게 이해 하면 됩 니 다.다음은 하나씩 설명 하 겠 습 니 다.
@SpringBootConfiguration

@Configuration
public @interface SpringBootConfiguration {
@Configuration 우 리 는 낯 설 지 않 습 니 다.컨 텍스트 에 추가 bean 을 등록 하거나 다른 설정 류 를 가 져 올 수 있 습 니 다.@SpringBootConfiguration 은 현재 클래스 가 설정 클래스 임 을 의미 합 니 다.
@EnableAutoConfiguration
EnableAutoConfiguration 의 목적 은 SpringBoot 의 자동 설정 체 제 를 시작 하 는 것 입 니 다.

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
1.AutoConfigurationPackage 는 기본 패키지 규칙 을 지정 합 니 다.

@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
AutoConfigurationPackage 주 해 는 이 주 해 를 추가 한 클래스 가 있 는 package 를 자동 설정 package 로 관리 하 는 역할 을 합 니 다.스프링 부 트 애플 리 케 이 션 이 시 작 될 때 기본적으로 시작 클래스 가 있 는 패 키 지 를 자동 으로 설정 하 는 패키지 로 사용 한 다 는 것 이다.그리고@Import 주 해 를 사용 하여 ioc 용기 에 주입 합 니 다.이렇게 하면 용기 에서 이 경 로 를 얻 을 수 있다.

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
      register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
   }

   @Override
   public Set<Object> determineImports(AnnotationMetadata metadata) {
      return Collections.singleton(new PackageImports(metadata));
   }

}
registerBean Definitions 방법 을 중점적으로 보 세 요.
방법의 두 번 째 매개 변 수 는new PackageImport(metadata).getPackageName()방법 으로 설정 합 니 다.
이어서 Package Import 의 구조 기 방법 을 살 펴 보 자.

PackageImports(AnnotationMetadata metadata) {
   AnnotationAttributes attributes = AnnotationAttributes
         .fromMap(metadata.getAnnotationAttributes(AutoConfigurationPackage.class.getName(), false));
   List<String> packageNames = new ArrayList<>(Arrays.asList(attributes.getStringArray("basePackages")));
   for (Class<?> basePackageClass : attributes.getClassArray("basePackageClasses")) {
      packageNames.add(basePackageClass.getPackage().getName());
   }
   if (packageNames.isEmpty()) {
      packageNames.add(ClassUtils.getPackageName(metadata.getClassName()));
   }
   this.packageNames = Collections.unmodifiableList(packageNames);
}
ClassUtils.getPackageName(metadata.getClassName())은@AutoConfigurationPackage 주 해 를 표시 하 는 클래스 의 전체 제한 이름 을 가 져 옵 니 다.
마지막 으로 Registrar 를 이용 하여 용기 에 일련의 구성 요 소 를 가 져 와 지정 한 가방 에 있 는 모든 구성 요 소 를 가 져 옵 니 다.
2、@Import(AutoConfigurationImportSelector.class)
Import 를 사용 하여 자동 설정 조건 에 맞 는 Bean 정 의 를 자동 으로 가 져 오고 IOC 용기 에 불 러 옵 니 다.

@Override
		public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
			Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
					() -> String.format("Only %s implementations are supported, got %s",
							AutoConfigurationImportSelector.class.getSimpleName(),
							deferredImportSelector.getClass().getName()));
			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
					.getAutoConfigurationEntry(annotationMetadata);
			this.autoConfigurationEntries.add(autoConfigurationEntry);
			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
				this.entries.putIfAbsent(importClassName, annotationMetadata);
			}
		}
1.getAutoConfigurationEntry(annotationMetadata)를 이용 합 니 다.용기 에 구성 요 소 를 대량으로 가 져 옵 니 다.
2.List configurations=getCandidate Configurations(annotationMetadata,attributes)를 호출 하여 용기 에 가 져 올 모든 설정 클래스 를 가 져 옵 니 다.
3.공장 을 이용 하여 맵loadSpringFactory(@Nullable ClassLoader classLoader)를 불 러 옵 니 다.모든 구성 요소 가 져 오기
4.META-INF/spring.factories 위치 에서 파일 을 불 러 옵 니 다.
현재 시스템 에 있 는 모든 META-INF/spring.factories 위 치 를 기본적으로 검색 합 니 다.
spring-boot-autoconfigure-2.4.4.RELEASE.jar 가방 안에 도 META-INF/spring.factories 가 들 어 있 습 니 다.
在这里插入图片描述
파일 에 spring-boot 가 시작 되 자마자 용기 에 불 러 올 모든 설정 클래스 spring-boot-autoconfigure-2.4.4.RELEASE.jar/META-INF/spring.factories 가 적 혀 있 습 니 다.모두 130 개의 자동 설정 클래스 입 니 다.
130 개 필드 의 모든 자동 설정 은 spring boot 가 시 작 될 때 기본적으로 모두 불 러 옵 니 다.xxxx AutoConfiguration 은 조건 에 따라 규칙(@Conditional)을 설치 하고 최종 적 으로 필요 에 따라 설정 합 니 다.
소결:
SpringBoot 는 우리 프로그램 에 세 가지 기능 을 사용 합 니 다.자동 설정,구성 요소 스 캔,그리고'응용 클래스'에서 추가 설정 을 정의 할 수 있 습 니 다.
@ComponentScan@Component응용 프로그램 이 있 는 패키지 에서 스 캔 을 사용 하여 어떤 Spring 주 해 를 스 캔 할 지 지정 합 니 다.
ServletWebServer Factory AutoConfiguration 을 예 로 들 면
130 개의 장면 에서 우 리 는 두 개의 구성 요 소 를 잘 알 고 있 습 니 다.ServletWebServerFactory AutoConfiguration 과 WebMvcAutoConfiguration 은 ServletWebServerFactory AutoConfiguration 을 예 로 들 어 SpringBoot 가 어떻게 자동 으로 설 치 된 웹 서버 인지 살 펴 보 겠 습 니 다.
在这里插入图片描述
주해 에서 우 리 는@conditional 로 시작 하 는 주 해 를 대량으로 보 았 습 니 다.즉,조건 조립,conditional 이 지정 한 조건 을 만족 시 키 면 구성 요 소 를 주입 합 니 다.@EnableConfigurationProperties(ServerProperties.class)+@ConfigurationProperties(prefix="server",ignore UnknownFields=true)는 설정 파일 에서 작 성 된 속성 을 읽 고 자바 빈 에 봉 하여 언제든지 사용 할 수 있 도록 합 니 다.
이때 우리 의 Tomcat 용 기 는 이미 Bean 형식 으로 IOC 용기 에 주입 되 었 다.
특정 자동 설정 클래스 를 사용 하지 않 는 방법
응용 프로그램 에서 특정 자동 설정 클래스 가 필요 하지 않 은 것 을 발견 하면 exclude 속성@SpringBootApplication을 사용 하여 사용 하지 않 을 수 있 습 니 다.다음 예제 와 같 습 니 다.

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
//@SpringBootApplication(excludeName = {"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"})
public class MyApplication {
}
이 클래스 가 클래스 경로 에 없 으 면excludeName주석 속성 을 사용 하고 완전히 제 한 된 이름(전체 이름 문자열)을 지정 할 수 있 습 니 다.배제 항목 을 정의 합 니 다.어떤 주석 단계 로 도 속성 을 사용 하여 정의 할 수 있 습 니 다.
총결산
  • SpringBoot 는 META-INF/spring.factories 의 모든 자동 설정 클래스 를 미리 불 러 옵 니 다.xxxxxAutoConfiguration
  • 모든 자동 설정 클래스 는 조건 에 따라 유효 하 며,기본적으로 설정 파일 이 지정 한 값 을 연결 합 니 다.xxxx Properties 에서 가 져 가세 요.xxxproperties 와 프로필 을 연결 하 였 습 니 다
  • 발 효 된 설정 류 는 용기 에 많은 구성 요 소 를 설치 합 니 다.용기 에 이런 구성 요소 가 있 으 면 이러한 기능
  • 이 있 는 것 과 같 습 니 다.
  • 맞 춤 형 설정
  • 사용자 가 직접@Bean 으로 기본 구성 요 소 를 교체 합 니 다.
    사용 자 는 이 구성 요소 가 가 져 온 프로필 의 어떤 값 인지 에 따라 스스로 수정 할 수 있 습 니 다.
    EnableAutoConfiguration―>xxxxx AutoConfiguration 검색―>조건 에 따라@Conditional 조립 구성 요소―>xxxxProperties 에 따라 속성 값 불 러 오기--->application.properties
    이 SpringBoot 자동 설정 원리 에 대해 당신 은 정말 알 고 있 습 니까?의 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringBoot 자동 설정 원리 에 관 한 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기