大家都知道springboot 在入口类会有个注解叫@SpringBootApplication注解,这其实是个组合的注解类spring boot通过此注解实现了自动装配:
@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 {
...
...
}
1、@SpringBootConfiguration
@SpringBootConfiguration这个注解其实很大程度上只是为了标注这个类是一个配置类。
其核心就在于继承了@Configuration注解, @Configuration 注解的类会将其中 @Bean 注解的方法所生成并返回的对象交由 Spring 容器来进行管理。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
1.1、@Configuration
@Configuration注解主要是通过ConfigurationClassPostProcessor类实现其主要的业务逻辑:
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else {
this.registriesPostProcessed.add(registryId);
this.processConfigBeanDefinitions(registry);
}
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
// 先获取所有configuration classes自身的bean definitions
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断configurationClassAttrbute属性是否存在,如果存在证明已经处理过了
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//判断是否是configuration类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if (!configCandidates.isEmpty()) {
// 预处理configuration的bean definitions
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
//单例bean的注册
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//通过ConfigurationClassParser解析所有configuration class的bean definitions
//统一封装成ConfigurationClass对象,包含所有支持元素:
// @Bean @Import @ImportResource @ComponentScans @PropertySource @PropertySources等
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析配置类
parser.parse(candidates);
parser.validate();
//前面解析配置类,只有 @Configuration 和通过 @ComponentScan 注解扫描出来的类才会加入到 BeanFactory 的 BeanDefinitionMap
// 其他注解,例如@Import、@Bean,会包装为 ConfigurationClass 类
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
//将ConfigurationClass对象解析为对应的bean definitions
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> {
return String.valueOf(configClasses.size());
}).end();
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//记录下最新的配置类
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet();
Iterator var13 = alreadyParsed.iterator();
while(var13.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass)var13.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var24 = newCandidateNames;
int var25 = newCandidateNames.length;
for(int var15 = 0; var15 < var25; ++var15) {
String candidateName = var24[var15];
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while(!candidates.isEmpty());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
}
}
}
看了以上代码可以了解到能被当做配置类的,不仅仅是@Configuration,还有@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解 Spring 认为也是配置类。不同的是 @Configuration 注解标记为FULL模式,而其他标记为LITE模式。
可以了解到通过增加@Configuration注解可以将类转化为BeanDefinition,在ApplicationContext后续的初始化中提供bean的初始化等功能。
2、@EnableAutoConfiguration
org.springframework.boot.autoconfigure.@EnableAutoConfiguration 是用于开启自动配置功能,是 自动配置的最核心的注解。代码如下:
@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 {};
}
2.1、@AutoConfigurationPackage
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
添加该注解的类所在的package 作为自动配置package进行管理,注册对应的bean到ioc容器中。
2.2、AutoConfigurationImportSelector
通过@import方式导入了AutoConfigurationImportSelector选择器,在启动过程中,调用的是其getAutoConfigurationEntry方法
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//获取配置数组
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//需要移除重复的配置
configurations = this.removeDuplicates(configurations);
//排除属性 -(1)
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//filter会过滤掉不符合配置的类,具体需要查看Condition
configurations = this.getConfigurationClassFilter().filter(configurations);
//自动配置导入的事件 -(2)
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
//(1)
protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
Set<String> excluded = new LinkedHashSet();
//获取注解上有关exclude的属性
excluded.addAll(this.asList(attributes, "exclude"));
//获取注解上有关excludeName的属性
excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
// 配置文件的 spring.autoconfigure.exclude 属性
excluded.addAll(this.getExcludeAutoConfigurationsProperty());
return excluded;
}
//(2)
private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
在META-INF/spring.factories配置中找到AutoConfigurationImportListener的所有监听器。
List<AutoConfigurationImportListener> listeners = this.getAutoConfigurationImportListeners();
if (!listeners.isEmpty()) {
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
Iterator var5 = listeners.iterator();
while(var5.hasNext()) {
AutoConfigurationImportListener listener = (AutoConfigurationImportListener)var5.next();
//设置Aware属性 (2.1)
this.invokeAwareMethods(listener);
//导入事件通知
listener.onAutoConfigurationImportEvent(event);
}
}
}
//(2.1)
private void invokeAwareMethods(Object instance) {
if (instance instanceof Aware) {
if (instance instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)instance).setBeanClassLoader(this.beanClassLoader);
}
if (instance instanceof BeanFactoryAware) {
((BeanFactoryAware)instance).setBeanFactory(this.beanFactory);
}
if (instance instanceof EnvironmentAware) {
((EnvironmentAware)instance).setEnvironment(this.environment);
}
if (instance instanceof ResourceLoaderAware) {
((ResourceLoaderAware)instance).setResourceLoader(this.resourceLoader);
}
}
}