@SpringBootApplication 주해 의 사용
12512 단어 @SpringBootApplication주해springboot
대부분의 설정 은 자바 클래스+주석 으로 대체 할 수 있 으 며,SpringBoot 프로젝트 에서 가장 많이 보 이 는 것 은@SpringBootApplication 주석 입 니 다.모든 SpringBoot 의 시작 클래스 에 표 시 됩 니 다.
이 주 해 는 SpringBoot 의 시작 과 자동 설정 에 어떤 영향 을 미 칩 니까?본 고 는 여러분 을 위해 그 원본 코드 를 해석 하고@SpringBootApplication 주해 의 신비 로 운 베일 을 벗 길 것 입 니 다.
본문
SpringBoot 프로젝트 의 자동 설정 에 관심 이 많아 서 소스 코드 를 배우 고 그 중의 일부 내용 을 정 리 했 습 니 다.오류 가 있 으 면 지적 해 주세요.말 을 많이 하지 않 고 소스 코드 를 직접 올 려 주세요.
@SpringBootApplication 주해 의 원본 코드 는 다음 과 같 습 니 다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
이것 은 복합 주해 로 모두 7 개의 서로 다른 주 해 를 포함 하고 다음은 이 7 개의 서로 다른 주 해 를 분석 하 는 것 을 볼 수 있다.주해
2.1.1 주석 1:@Target({ElementType.TYPE})
주해 작용 범 위 를 나타 내 는 데 사용 되 며,TYPE 는 작용 범 위 를 클래스 나 인터페이스 로 나타 낸다.
2.1.2 주석 2:@Retention(RetentionPolicy.RUNTIME)
2.1.3 주석 3:@Documented
이 주석 은 자바 doc 에 의 해 기록 되 었 음 을 나타 낸다.
2.1.4 주석 4:@Inherited
주석 에 부모 클래스 가@SpringBootApplication 주 해 를 추가 하면 하위 클래스 도 이 주 해 를 계승 합 니 다(인터페이스 구현 클래스 가 잘못 되 었 습 니 다).
2.1.5 주석 5:@SpringBootConfiguration
바 텀 은@Configuration 주석 입 니 다.원본 코드 는 다음 과 같 습 니 다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
2.1.6 주석 6:@ComponetScan@Componentscan 이라는 주 해 는 Spring 에서 매우 중요 합 니 다.XML 설정 의 요소@Componentscan 에 대응 하 는 기능 은 조건 에 맞 는 구성 요소(예 를 들 어@Component 와@Repository 등)나 bean 정 의 를 자동 으로 검색 하고 불 러 오 는 것 입 니 다.최종 적 으로 이 bean 정 의 를 IoC 용기 에 불 러 옵 니 다.
basePackages 등 속성 을 통 해 세분 화 된 맞 춤 형@Componentscan 자동 스 캔 범 위 를 지정 하지 않 으 면 기본 Spring 프레임 워 크 는 성명@Componentscan 이 있 는 패키지 에서 스 캔 합 니 다.따라서 SpringBoot 의 시작 클래스 는 루트 패키지 아래 에 두 는 것 이 좋 습 니 다.기본 값 으로 basePackages 를 지정 하지 않 기 때 문 입 니 다.
2.2 주석:@EnableAutoConfiguration
개인 적 으로@EnableAutoConfiguration 이라는 Annotation 의 가장 중요 한 역할 은@Import 의 도움 을 받 아 자동 설정 조건 에 맞 는 모든 bean 정 의 를 IoC 용기 에 불 러 오 는 것 으로 요약 할 수 있 습 니 다.
그 소스 코드 는 다음 과 같다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@AutoConfiguration Package 와@Import(AutoConfiguration ImportSelector.class)두 개의 주 해 를 주목 해 야 합 니 다.2.2.1 주석:@AutoConfigurationPackage
원본 코드 는 다음 과 같 습 니 다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
이 주해 의 핵심 은 사실 Import 주해 임 을 알 수 있 습 니 다.이 주해 가 표 시 된 클래스 에 대한 패 키 지 는 AutoConfiguration Packages 로 등록 해 야 한 다 는 뜻 입 니 다.이어서 Registrar 라 는 종 류 를 보 세 요.
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
//metadata
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
이 클래스 의 핵심 방법 은 register 방법 입 니 다.
private static final String BEAN = AutoConfigurationPackages.class.getName();
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
if (registry.containsBeanDefinition(BEAN)) {
BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
}
else {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(BasePackages.class);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN, beanDefinition);
}
}
register 방법의 논 리 는 매우 뚜렷 합 니 다.만약 에 이 bean 이 등록 되 었 다 면 구조 함수 파라미터 값 을 얻 고 가방 이름 을 추가 합 니 다.그렇지 않 으 면 새로운 bean 정 의 를 만 들 고 등록 합 니 다.@AutoConfigurationPackage 라 는 주 해 를 통 해 가방 에 있 는 모든 구성 요 소 를 등록 할 수 있 습 니 다.2.2.2 주석:@Import(AutoConfigurationImportSelector.class)
이 주 해 는 AutoConfiguration ImportSelector 와 같은 핵심 방법 을 가 져 왔 습 니 다.selectImports 방법 으로 ImportSelector 인 터 페 이 스 를 실현 합 니 다.방법 은 pom.xml 파일 에 설 정 된 jar 패키지 와 구성 요 소 를 기반 으로 가 져 옵 니 다.그래서 방법 은 Class 전체 경로 의 String 배열 을 되 돌려 줍 니 다.되 돌아 오 는 Class 는 Spring 용기 에 의 해 관 리 됩 니 다.방법 원본 은 다음 과 같 습 니 다.
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
이 방법 은 구조 도 뚜렷 하 다.우선 isEnabled 방법 으로 가 져 올 필요 가 있 는 지 판단 하고 가 져 올 필요 가 있 으 면 loadMetadata 방법 으로 설정 정 보 를 얻 고 getAutoConfigurationEntry 를 통 해 자동 으로 조립 한다.isEnabled 방법 원본 은 다음 과 같 습 니 다.
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
return true;
}
이 방법 은 EnableAutoConfiguration.ENABLED 를 통 해OVERRIDE_PROPERTY 이 설정 항목 은 자동 설정 이 필요 한 지 여 부 를 판단 합 니 다.기본 값 은 true 입 니 다.loadMetadata 방법 원본 코드 는 다음 과 같 습 니 다.
protected static final String PATH = "META-INF/" + "spring-autoconfigure-metadata.properties";
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try {
Enumeration<URL> urls = (classLoader != null) ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path);
Properties properties = new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils.loadProperties(new UrlResource(urls.nextElement())));
}
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", ex);
}
}
static AutoConfigurationMetadata loadMetadata(Properties properties) {
return new PropertiesAutoConfigurationMetadata(properties);
}
이 방법 을 보면 META-INF/spring-autoconfigure-metadata.properties 의 모든 설정 정 보 를 불 러 오고 AutoConfigurationMetadata 대상 으로 포장 하여 되 돌려 줍 니 다.주:spring-autoconfigure-metadata.properties 파일 은 spring-boot-autoconfigure-2.1.9.RELEASE.jar/META-INF 에 있 습 니 다.
getAutoConfigurationEntry 방법 원본 코드 는 다음 과 같 습 니 다.
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
이 방법 은 AutoConfiguration 의 주류 프로 세 스 방법 입 니 다.이 방법의 모든 줄 을 하나의 절차 로 볼 수 있 습 니 다.그러면 처리 절 차 는 다음 과 같 습 니 다.1. @EnableAutoConfiguration 주석 을 설정 한 속성 값 getAttribute 를 불 러 오 는 방법:
protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClass().getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
+ " annotated with " + ClassUtils.getShortName(name) + "?");
return attributes;
}
2.META-INF/spring.factories 파일 에서@EnableAutoConfiguration 으로 클래스 이름 을 key 로 완전히 제한 하 는 value,getCandidate Configurations 방법 을 얻 습 니 다.
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
그 중에서 SpringFactories Loader.loadFactory Names()는 주어진 클래스 로 더 를 사용 하여 META-INF/spring.factories 에서 주어진 유형의 공장 을 불 러 오 는 완전 한정 클래스 를 사용 하 는 역할 을 합 니 다.3.무 거 워 지기;
4.제거 해 야 할 클래스 의 클래스 이름 을 가 져 옵 니 다.이 클래스 는@EnableAutoConfiguration 주석 에서 설정 할 수 있 습 니 다.
5.이 두 집합 검사 하기;
6.제거 해 야 할 종 류 를 제거 하기;
7.OnBeanCondition,OnClassCondition 등 조건 에 따라 여과(관심 이 있 으 면 깊이 이해 할 수 있다).
8.방송 이벤트,AutoConfiguration ImportListener 의 모든 실현 클래스 를 얻 은 다음 에 이 벤트 를 생 성하 여 방송 합 니 다.
9.설치 와 제거 가 필요 한 클래스 의 완전 한정 명 을 AutoConfigurationEntry 대상 으로 봉 하여 되 돌려 줍 니 다.
따라서@EnableAutoConfiguration 은 classpath 에서 모든 META-INF/spring.factories 설정 파일 을 찾 고,이 중 EnableAutoConfiguration 에 대응 하 는 설정 항목 을@Configuration 이 표 시 된 IoC 용기 설정 클래스 로 반사 실례 화하 여 IoC 용기 에 불 러 옵 니 다.
소결
상기 분석 을 통 해 알 수 있 듯 이@SpringBootApplication 주해 의 작 동 은@SpringApplicationConfiguration 성명 을 통 해 클래스 가 설정 클래스 로 표시 되 어 AnnotationConfigApplication Context 에서 스 캔 되 고 Spring 용 기 를 초기 화 합 니 다.
@EnableAutoConfiguration 을 통 해 필요 한 구성 요 소 를 스 캔 하고 걸 러 내 고 불 러 옵 니 다.@Component Scan 을 통 해@Component 와 그 하위 주석 이 표 시 된 모든 종 류 를 검색 하고 등록 합 니 다.이러한 주해 의 공동 운영 은 springboot 프로젝트 의 강력 한 자동 설정 능력 을 실현 하 였 다.
이상 은@SpringBootApplication 주해 의 사용 에 대한 상세 한 내용 입 니 다.@SpringBootApplication 주해 의 사용 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
@SpringBootApplication 주해 의 사용basePackages 등 속성 을 통 해 세분 화 된 맞 춤 형@Componentscan 자동 스 캔 범 위 를 지정 하지 않 으 면 기본 Spring 프레임 워 크 는 성명@Componentscan 이 있 는 패...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.