文章来源:https://my.oschina.net/lt0314/blog/4335365
源码分析@EnableAutoConfiguration在SpringBoot中的加载和实例化过程
万里长征第一步,我们先理解下什么是EnableAutoConfiguration?
什么是EnableAutoConfiguration注解?
在哪?
org.springframework.boot.autoconfigure.EnableAutoConfiguration
EnableAutoConfiguration概述
我们先来看下源码
package org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.annotation.Conditional;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.core.io.support.SpringFactoriesLoader;/** * Enable auto-configuration of the Spring Application Context, attempting to guess and * configure beans that you are likely to need. Auto-configuration classes are usually * applied based on your classpath and what beans you have defined. For example, If you * have {@code tomcat-embedded.jar} on your classpath you are likely to want a * {@link TomcatEmbeddedServletContainerFactory} (unless you have defined your own * {@link EmbeddedServletContainerFactory} bean). * * When using {@link SpringBootApplication}, the auto-configuration of the context is * automatically enabled and adding this annotation has therefore no additional effect. * * Auto-configuration tries to be as intelligent as possible and will back-away as you * define more of your own configuration. You can always manually {@link #exclude()} any * configuration that you never want to apply (use {@link #excludeName()} if you don't * have access to them). You can also exclude them via the * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied * after user-defined beans have been registered. * * The package of the class that is annotated with {@code @EnableAutoConfiguration}, * usually via {@code @SpringBootApplication}, has specific significance and is often used * as a 'default'. For example, it will be used when scanning for {@code @Entity} classes. * It is generally recommended that you place {@code @EnableAutoConfiguration} (if you're * not using {@code @SpringBootApplication}) in a root package so that all sub-packages * and classes can be searched. * * Auto-configuration classes are regular Spring {@link Configuration} beans. They are * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class). * Generally auto-configuration beans are {@link Conditional @Conditional} beans (most * often using {@link ConditionalOnClass @ConditionalOnClass} and * {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations). */@SuppressWarnings("deprecation")@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {};}
类图
注意“@Import(EnableAutoConfigurationImportSelector.class)” 部分。后边源码分析中会使用到。
说明
EnableAutoConfiguration注解的功能大概如下。
开启Spring应该上下文的自动配置,尽可能去加载需要的配置Beans。自动配置类,一般是根据你的classpath路径来应用的。
当你使用了SpringBootApplication注解,在context中自动加载配置就已经开启,不需要其他操作。
可以通过exclude()传入Class类型;excludeName() 传入名称来排除其他类型的加载。自动加载的配置始终是在普通用户定义的Bean加载之后执行。
默认EnableAutoConfiguration扫描的是当前启用注解的Class对象的目录作为root目录。所以这个目录下的所有子目录都会被扫描。
自动装载的配置类,也是常规的SpringBean(被@Configuration修饰,@Configuration则被@Component修饰(如果你写的@Configuration在启动类的包名下,开启注解扫描的情况下,也是会把@Configuration注册为Bean对象。))。当然也可以通过SpringFactoriesLoader的机制来定位到对应的org.springframework.boot.autoconfigure.EnableAutoConfiguration类(不在同用户扫描包目录中)。
一般配合Conditional、ConditionalOnClass、ConditionalOnMissingBean一起使用。
测试项目
│ pom.xml└─src └─main ├─java │ └─com │ └─baigt │ ├─autoconfig │ │ BaigtAutoConfig.java │ │ │ └─sb │ SBStarter.java │ └─resources └─META-INF spring.factories
pom
<?xml version="1.0" encoding="UTF-8"?> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baigt SpringBootCodeAnalyze 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 1.5.14.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-maven-plugin
BaigtAutoConfig
注意和启动类不在一个目录中
package com.baigt.autoconfig;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 测试Autoconfig */@Configurationpublic class BaigtAutoConfig { @Bean public String env(){ return new String("Baigt Test"); }}
SBStarter
注意和config不在一个目录 中
package com.baigt.sb;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/** * 测试@EnableAutoConfig加载的流程(加载自定义的配置类,不在同一个目录中) */@SpringBootApplicationpublic class SBStarter{ public static void main(String[] args) { SpringApplication sb=new SpringApplication(SBStarter.class); ConfigurableApplicationContext run = sb.run(args); System.out.println(run.getBean("baigt",String.class)); }}
spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baigt.autoconfig.BaigtAutoConfig
正题(源码)
我们只分析和EnableAutoConfiguration相关的源码。
new SpringApplication
初始化环境(是否是web),设置ApplicationContextInitializer、ApplicationListener,设置启动类的class到mainApplicationClass上。我们的例子中不是web环境。
//初始化入口 public SpringApplication(Object... sources) { initialize(sources); } 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(); }
SpringApplication
启动SpringBoot项目,我们这里只关注Context创建和实例化AutoConfig相关的逻辑。注意我们的示例不是Web项目,只是个普通的java项目。
run
这里主要有三处,一个是createApplicationContext,一个是prepareContext,一个是refreshContext。
public ConfigurableApplicationContext run(String... args) { //... ConfigurableApplicationContext context = null; //。。。 listeners.starting(); try { //.... //注意这部分 创建context context = createApplicationContext(); analyzers = new FailureAnalyzers(context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新context(实例化各种post以及Bean) refreshContext(context); afterRefresh(context, applicationArguments); // ... return context; } catch (Throwable ex) { } }
后边再讲refreshContext。
createApplicationContext
创建Context,我们不是web项目哦。所以我们Context是AnnotationConfigApplicationContext类型。
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." + "annotation.AnnotationConfigApplicationContext"; protected ConfigurableApplicationContext createApplicationContext() { Class> contextClass = this.applicationContextClass; if (contextClass == null) { try { //前边我们分析到,不是web 环境!!所以我们Context是AnnotationConfigApplicationContext类型。 contextClass = Class.forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); } catch (ClassNotFoundException ex) { // } }//这里实例化的是 AnnotationConfigApplicationContext类(无参构造) return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); }
AnnotationConfigApplicationContext
类图
我们先看下类图。
是BeanDefinitionRegistry
是BeanFactory
是Resource
AnnotationConfigApplicationContext()
从前边我们了解到,我们的context是AnnotationConfigApplicationContext,无参构造会实例化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。因为Autoconfig相关的都会被@Configuration修饰,所以我们只关注AnnotatedBeanDefinitionReader,它是注解BeanDefinition读取器。我们主要分析说明的是这个。
public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader(BeanDefinitionRegistry)
AnnotationConfigApplicationContext就是一个BeanDefinitionRegistry实例。将AnnotationConfigApplicationContext的实例传递到AnnotatedBeanDefinitionReader中使用。下边我们分析这个AnnotatedBeanDefinitionReader类实例化过程中都做了什么。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
AnnotationConfigUtils
registerAnnotationConfigProcessors
注册注解相关的后置处理器,比如ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory等。我们这里只关注配置类相关的源码部分。
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { registerAnnotationConfigProcessors(registry, null); } public static Set registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); Set beanDefs = new LinkedHashSet(4); // 注册ConfigurationClassPostProcessor处理器 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } return beanDefs; }
ConfigurationClassPostProcessor
类图
是BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor
是PriorityOrdered
上边两个接口,是关键,后边要用到!!!!
registerPostProcessor
注册ConfigurationClassPostProcessor处理器到BeanFactory中。
private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }
BeanDefinitionRegistry
从入口处我们知道,registry是AnnotationConfigApplicationContext的实例,被传递过来。它的父类是GenericApplicationContext。在无参实例化时,GenericApplicationContext会持有一个DefaultListableBeanFactory对象。
结构图
BeanFactory
GenericApplicationContext的实例化BeanFactory过程
private final DefaultListableBeanFactory beanFactory; public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); } public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { this.beanFactory.registerBeanDefinition(beanName, beanDefinition); }
DefaultListableBeanFactory
registerBeanDefinition
将BeanDefinition定义交给BeanFactory管理。主要在beanDefinitionMap、beanDefinitionNames这几个map对象中存储。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set updatedSingletons = new LinkedHashSet(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
至此ConfigurationClassPostProcessor已经被BeanFactory管理起来。下边我们再来分析后边这个对象是怎么使用。那么我们再次回到SpringApplication的Run方法中prepareContext和**refreshContext(context);**部分。
SpringApplication
prepareContext
我们重点关注下load部分,传入的是当前启动类。source是new SpringApplication时传入的Class对象,也就是SBStarter.class。
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { //。。。。。 // Load the sources Set sources = getSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[sources.size()])); // 。。。。 }
load
加载bean到ApplicationContext中.BeanDefinitionLoader是持有Context对象的。Context本身就是个registry.
protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug( "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } BeanDefinitionLoader loader = createBeanDefinitionLoader( getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) { loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader != null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment != null) { loader.setEnvironment(this.environment); } loader.load(); }
BeanDefinitionLoader
load
我们的source就是SBStarter.class,也就是会执行load((Class>) source)。最后注册成类型AnnotatedBeanDefinition的BeanDefinition。
public int load() { int count = 0; for (Object source : this.sources) { count += load(source); } return count; } private int load(Object source) { Assert.notNull(source, "Source must not be null"); if (source instanceof Class>) { return load((Class>) source); } if (source instanceof Resource) { return load((Resource) source); } if (source instanceof Package) { return load((Package) source); } if (source instanceof CharSequence) { return load((CharSequence) source); } throw new IllegalArgumentException("Invalid source type " + source.getClass()); } private int load(Class> source) { if (isGroovyPresent()) { // Any GroovyLoaders added in beans{} DSL can contribute beans here if (GroovyBeanDefinitionSource.class.isAssignableFrom(source)) { GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class); load(loader); } } //如果SBStarter是个组件的话,会注册到beanDefinition上去。 if (isComponent(source)) { //AnnotatedBeanDefinitionReader是前边实例化时创建。目的是注册一个类型AnnotatedBeanDefinition的BeanDefinition this.annotatedReader.register(source); return 1; } return 0; }
isComponent
@SpringBootApplication是SpringBootConfiguration类型的。
SpringBootConfiguration是Configuration类型的。
Configuration是Component类型的
最后SBStarter也就是个Component类型的
AnnotatedBeanDefinitionReader
register
//annotatedClasses=com.baigt.sb.SBStarter public void register(Class>... annotatedClasses) { for (Class> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } }
registerBean
这里我们要注意的是我们是创建了一个AnnotatedGenericBeanDefinition类型的BeanDefinition对象通过BeanDefinitionReaderUtils工具进行注册的。
public void registerBean(Class> annotatedClass) { registerBean(annotatedClass, null, (Class extends Annotation>[]) null); } public void registerBean(Class> annotatedClass, Class extends Annotation>... qualifiers) { registerBean(annotatedClass, null, qualifiers); } public void registerBean(Class> annotatedClass, String name, Class extends Annotation>... qualifiers) { //注意这里,我是一个AnnotatedGenericBeanDefinition类型的BeanDefinition实例 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //我是在这里和context关联上的 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
BeanDefinitionReaderUtils
registerBeanDefinition
注意传入的registry,AnnotationConfigApplicationContext本身就是个BeanDefinitionRegistry。而这个部分最后调用的是AnnotationConfigApplicationContext在实例化中隐式实例化父类GenericApplicationContext时创建的一个DefaultListableBeanFactory对象的registerBeanDefinition方法。这就又回到了ConfiguationClassPostProcessor时registerBeanDefinition的过程。因此这里就不再继续深入分析。最终的结果是交给了BeanFactory统一管理BeanDefinition!!
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
SpringApplication
refreshContext
刷新Context和注册关机钩子;注意传入的是一个AnnotationConfigApplicationContext实例。我们主要分析refresh
private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } } protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); }
刷新用的是AbstractApplicationContext中的refresh方法。
AbstractApplicationContext
org.springframework.context.support.AbstractApplicationContext
refresh
在ConfigurationClassPostProcessor那一部分,我们知道它是一个BeanFactoryPostProcessor。所以我们一定要看的是invokeBeanFactoryPostProcessors部分的逻辑,其次因为Configuration注解类中相关的如@Bean修饰的方法也是要实例化的,所以我们还要看的是finishBeanFactoryInitialization中的逻辑。
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // refresh的前置准备,比如设置startTime,开启激活状态、关闭close状态等等等 prepareRefresh(); //告诉子类去刷新内容Bean工厂(从类图中可以明显看出来入口类实例也是个bean工厂) // 观察和刷新BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //提前设置一些在该context中使用的属性,比如Classloader、Callback、environment等 prepareBeanFactory(beanFactory); try { // 通知context子类,后置处理beanFactory。比如用一系列的Webcontext子类 postProcessBeanFactory(beanFactory); // 将BeanFactoryPostProcessor在当前Context中注册为Bean invokeBeanFactoryPostProcessors(beanFactory); // 注册BeanPostProcessor来拦截Bean创建的后置处理。 registerBeanPostProcessors(beanFactory); // 为当前Context初始化MessageSource initMessageSource(); // 为当前context初始化应用事件广播 initApplicationEventMulticaster(); // 初始化其他特殊的bean对象 比如webcontext onRefresh(); // 检查监听Bean 并发布他们(ApplicationListener) registerListeners(); // 实例化BeanFactory中所有的其他的单例对象集合(非延迟的) finishBeanFactoryInitialization(beanFactory); // 最后发布LifecycleProcessor和ContextRefreshedEvent事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 失败销毁bean destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
invokeBeanFactoryPostProcessors
使用委托模式来执行BeanFactoryPostProcessors。注意委托类PostProcessorRegistrationDelegate接收的beanFactory是我们的Context实例(是个BeanFactory,同时它也持有ConfigurationClassPostProcessor的BeanDefinition信息)。getBeanFactoryPostProcessors部分中的BeanFactoryPostProcessors是其他步骤中注入的后置器,我们这里不关注。直接进委托类中继续 分析。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
PostProcessorRegistrationDelegate
org.springframework.context.support.PostProcessorRegistrationDelegate
invokeBeanFactoryPostProcessors
我们不关注beanFactoryPostProcessors部分传入的参数,因为ConfigurationClassPostProcessor不在此。前边我们分析到ConfigurationClassPostProcessor同时是一个BeanDefinitionRegistryPostProcessor,invokeBeanFactoryPostProcessors中与此有关的逻辑我们重点看下!!!
首先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
其次执行实现Ordered接口的BeanDefinitionRegistryPostProcessor
最后执行其他所有的BeanDefinitionRegistryPostProcessor对象
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set processedBeans = new HashSet(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new LinkedList(); List registryProcessors = new LinkedList(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { //省略 } List currentRegistryProcessors = new ArrayList(); // 首先执行一个实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors!!! 这不就是我们的ConfigurationClassPostProcessor嘛!!! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 其次执行一个实现Ordered接口的BeanDefinitionRegistryPostProcessors!!! 且没有在processedBeans中 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 最后执行其他 BeanDefinitionRegistryPostProcessor boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List priorityOrderedPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List orderedPostProcessors = new ArrayList(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List nonOrderedPostProcessors = new ArrayList(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
我们只关注第一个,因为ConfigurationClassPostProcessor实现了PriorityOrdered接口!!!!
invokeBeanDefinitionRegistryPostProcessors
传入的postProcessors是ConfigurationClassPostProcessor,传入的registry则是我们的AnnotationConfigApplicationContext(前边也提到了他也是个BeanDefinitionRegistry)。哇偶!终于到了我们ConfigurationClassPostProcessor的源码部分了(postProcessBeanDefinitionRegistry)
private static void invokeBeanDefinitionRegistryPostProcessors( Collection extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
ConfigurationClassPostProcessor
postProcessBeanDefinitionRegistry
这个方法比较简单,有些检查,核心方法是processConfigBeanDefinitions。我们跟进去看下。
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); } if (this.factoriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + registry); } this.registriesPostProcessed.add(registryId); processConfigBeanDefinitions(registry); }
processConfigBeanDefinitions
类的Doc说明是构建和验证由Configuration注解修饰的Class对象。注意注入的BeanDefinitionRegistry是一个DefaultListableBeanFactory实例,因此也是一个SingletonBeanRegistry对象。具体可自行分析类图的继承关系。这里会加载我们启动类SBStarter这个配置类。
启动类SBStarter是我们自定义的类,是在org.springframework.boot.SpringApplication#prepareContext步骤中注入的。
/** * Build and validate a configuration model based on the registry of * {@link Configuration} classes. */ public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List configCandidates = new ArrayList(); String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //是否已经加载过 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { } //没有加载过 就放入configCandidates集合中 这里只有我们手写的启动类SBStarter是没有被加载过的。具体加载过程上边我们已经说过了 我们这里看下SBStarter的后续操作。 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 没有就快速返回 if (configCandidates.isEmpty()) { return; } // 根据Order排序 Collections.sort(configCandidates, new Comparator() { @Override public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } }); // Detect any custom bean name generation strategy supplied through the enclosing application context SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } // 解析每一个 @Configuration class 这里只解析到我们开启SpringBootApplication注解的SBStarter类是Configuration class,我们写的那个不在扫描路径中。 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set candidates = new LinkedHashSet(configCandidates); Set alreadyParsed = new HashSet(configCandidates.size()); do { //从SBStarter为入口解析Configuration相关Class parser.parse(candidates); parser.validate(); Set configClasses = new LinkedHashSet(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } // 在这里加载成BeanDefinition 并交给BeanFactory管理。 this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set oldCandidateNames = new HashSet(Arrays.asList(candidateNames)); Set alreadyParsedClasses = new HashSet(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { 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()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes if (sbr != null) { if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } } if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } }
ConfigurationClassParser
parse(set)
这里主要分析两个部分,一个是再次Parse(不同入参),一个是完整流程(processDeferredImportSelectors())
SBStarter注入的BeanDefiniton是个AnnotatedBeanDefinition
触发parse(AnnotationMetadata metadata, String beanName)调用
public void parse(Set configCandidates) { this.deferredImportSelectors = new LinkedList(); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); } } processDeferredImportSelectors(); }
parse(AnnotationMetadata, String)
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(metadata, beanName)); }
processConfigurationClass
处理ConfigurationClass对象。主要是doProcessConfigurationClass部分。
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } ConfigurationClass existingClass = this.configurationClasses.get(configClass); if (existingClass != null) { if (configClass.isImported()) { if (existingClass.isImported()) { existingClass.mergeImportedBy(configClass); } // Otherwise ignore new imported config class; existing non-imported class overrides it. return; } else { // Explicit bean definition found, probably replacing an import. // Let's remove the old one and go with the new one. this.configurationClasses.remove(configClass); for (Iterator it = this.knownSuperclasses.values().iterator(); it.hasNext();) { if (configClass.equals(it.next())) { it.remove(); } } } } // Recursively process the configuration class and its superclass hierarchy. SourceClass sourceClass = asSourceClass(configClass); do { sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); this.configurationClasses.put(configClass, configClass); }
doProcessConfigurationClass
这里很重要了,也是很复杂的一部分。不过也是SpringBoot可以不使用Xml就能扫描注解相关类的关键部分。下边大概涉及到@PropertySources,@PropertySource,@ComponentScans.class, @ComponentScan.class,@Import,@ImportSource等等。我们主要关注的是@Import部分。为什么?因为我们还是目的就是想看@EnableAutoConfiguration是怎么加载不同目录下的配置类,并实例化的!!! 而在@EnableAutoConfiguration中有使用了@Import,@Import(EnableAutoConfigurationImportSelector.class)
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 处理成员class 比如内部class 静态class processMemberClasses(configClass, sourceClass); // 处理 @PropertySource annotations for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } // 处理 @ComponentScan annotations Set componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { for (AnnotationAttributes componentScan : componentScans) { // The config class is annotated with @ComponentScan -> perform the scan immediately Set scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if needed for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // 处理 any @Import annotations 我们Spring.factories就是在这一部分 会解析出org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector processImports(configClass, sourceClass, getImports(sourceClass), true); // 处理 any @ImportResource annotations 如果手动引入了xml配置文件 基本是这种的 if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); String[] resources = importResource.getStringArray("locations"); Class extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // Process individual @Bean methods Set beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces processInterfaces(configClass, sourceClass); // Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; }
processImports
从EnableAutoConfigurationImportSelector中获取Spring.factories中key=org.springframework.boot.autoconfigure.EnableAutoConfiguration的需要自动化加载的配置类。最后存放在deferredImportSelectors集合中。
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection importCandidates, boolean checkForCircularImports) { if (importCandidates.isEmpty()) { return; } if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { for (SourceClass candidate : importCandidates) { if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class> candidateClass = candidate.loadClass(); //实例化EnableAutoConfigurationImportSelector 存放在deferredImportSelectors中 ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else { String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection importSourceClasses = asSourceClasses(importClassNames); processImports(configClass, currentSourceClass, importSourceClasses, false); } } else { //省略代码 } } } catch (BeanDefinitionStoreException ex) { // } finally { this.importStack.pop(); } } }
parse(Set configCandidates)
返回到此处,执行 processDeferredImportSelectors方法。处理刚才存放在deferredImportSelectors中的import对象。
public void parse(Set configCandidates) { this.deferredImportSelectors = new LinkedList(); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (BeanDefinitionStoreException ex) { throw ex; } } //处理我们刚才存放在这里的deferredImportSelectors processDeferredImportSelectors(); }
processDeferredImportSelectors
调用ImportSelector类的selectImports方法,最后递归调用processImports来处理其他Configuration类。这里我们来看下EnableAutoConfigurationImportSelector的selectImports方法。
private void processDeferredImportSelectors() { List deferredImports = this.deferredImportSelectors; this.deferredImportSelectors = null; Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR); for (DeferredImportSelectorHolder deferredImport : deferredImports) { ConfigurationClass configClass = deferredImport.getConfigurationClass(); try { String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata()); processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false); } catch (BeanDefinitionStoreException ex) { } } }
EnableAutoConfigurationImportSelector
@EnableAutoConfiguration 中@Import引入的ImportSelector。我们Ctrl+F12来看下selectImports方法在哪?
AutoConfigurationImportSelector
EnableAutoConfigurationImportSelector 的父类。selectImports方法所在的类。我们重点关注getCandidateConfigurations方法的源码。通过SpringFactoriesLoader.loadFactoryNames来加载spring.factories中对应key为EnableAutoConfiguration的ConfigClass集合。
public String[] selectImports(AnnotationMetadata annotationMetadata) { //如果不是EnableAutoConfigurationImportSelector的时候 isEnabled==true 默认AutoConfigurationImportSelector的isEnable==true ,走后边的逻辑 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } try { AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); //获取需要自动化加载配置类 这个是核心类。我们下边分析 List configurations = getCandidateConfigurations(annotationMetadata, attributes); //删除重复的configClass configurations = removeDuplicates(configurations); //排序 configurations = sort(configurations, autoConfigurationMetadata); Set exclusions = getExclusions(annotationMetadata, attributes); //删除exclue掉的Class checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); //处理AutoConfigurationImportFilter configurations = filter(configurations, autoConfigurationMetadata); //处理AutoConfigurationImportListener fireAutoConfigurationImportEvents(configurations, exclusions); return configurations.toArray(new String[configurations.size()]); } catch (IOException ex) { throw new IllegalStateException(ex); } } // 通过SpringFactoriesLoader加载EnableAutoConfiguration相关的配置类 protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List 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; } // 要通过SpringFactories来加载的类 protected Class> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }
SpringFactoriesLoader
loadFactoryNames
//从META-INF/spring.factories的文件中解析内容(所有的spring.factories。包括spring-boot-1.5.14.RELEASE.jar中的)。从中拿到org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类,比如我们自己定义的BaigtAutoConfig类。
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; public static List loadFactoryNames(Class> factoryClass, ClassLoader classLoader) { //factoryClassName=org.springframework.boot.autoconfigure.EnableAutoConfiguration String factoryClassName = factoryClass.getName(); try { //从META-INF/spring.factories的文件中解析内容(所有的spring.factories。包括spring-boot-1.5.14.RELEASE.jar中的) Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List result = new ArrayList(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); //转换为Properties Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); //从properties中获取EnableAutoConfiguration对应的Value 比如我们的com.baigt.autoconfig.BaigtAutoConfig String factoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException ex) { } }
接下来我们返回到ConfigurationClassPostProcessor的processConfigBeanDefinitions方法。
ConfigurationClassPostProcessor
processConfigBeanDefinitions
接下来我们来看下**this.reader.loadBeanDefinitions(configClasses);**加载我们配置类,交给beanFactory管理。
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List configCandidates = new ArrayList(); String[] candidateNames = registry.getBeanDefinitionNames(); //。。。。 // Parse each @Configuration class ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set candidates = new LinkedHashSet(configCandidates); Set alreadyParsed = new HashSet(configCandidates.size()); do { parser.parse(candidates); parser.validate(); Set configClasses = new LinkedHashSet(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content 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); }
ConfigurationClassBeanDefinitionReader
loadBeanDefinitions
我们只关注我们定义的配置类(BaigtAutoConfig)
public void loadBeanDefinitions(Set configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); for (ConfigurationClass configClass : configurationModel) { loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }
loadBeanDefinitionsForConfigurationClass
处理配置类中上的注解(比如Import),以及@Bean方法
private void loadBeanDefinitionsForConfigurationClass( ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { if (trackedConditionEvaluator.shouldSkip(configClass)) { String beanName = configClass.getBeanName(); if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; } // BaigtAutoConfig是通过Import(SelectImports)来创建的ConfigClass 所以这里是true if (configClass.isImported()) { //将该配置类注册为BeanDefinition registerBeanDefinitionForImportedConfigurationClass(configClass); } // BaigtAutoConfig中有个@Bean修饰的方法 也会执行这个方法 for (BeanMethod beanMethod : configClass.getBeanMethods()) { loadBeanDefinitionsForBeanMethod(beanMethod); } //配置类中如果使用了ImportSource注解和ImportBeanDefinitionRegistrar。则去加载相关内容成BeanDefinition loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
registerBeanDefinitionForImportedConfigurationClass
将BaigtAutoConfig配置类注册为BeanDefinition
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { AnnotationMetadata metadata = configClass.getMetadata(); AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata); ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName()); String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry); AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 注册我们的BaigtAutoConfig this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition()); configClass.setBeanName(configBeanName); }
loadBeanDefinitionsForBeanMethod
解析@Bean方法中相关的属性,比如设置factoryMethod、InitMethod、DestroyMethod、beanName、alias等。也设置lazy、dependOn等等。最后this.registry.registerBeanDefinition(beanName, beanDefToRegister); 完成配置类中@Bean方法的注册。this.registry又是我们前边提到的DefaultListableBeanFactory。交给BeanFactory管理。
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); // 这一步(shouldSkip)会设置mergedBeanDefinitions中该name的scope为单例。即使没有这个在最后判断的时候scope=""时也等价于单例 if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; } if (configClass.skippedBeanMethods.contains(methodName)) { return; } // Consider name and any aliases AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); List names = new ArrayList(Arrays.asList(bean.getStringArray("name"))); String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden for (String alias : names) { this.registry.registerAlias(beanName, alias); } // Has this effectively been overridden before (e.g. via XML)? if (isOverriddenByExistingDefinition(beanMethod, beanName)) { if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) { throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(), beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!"); } return; } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) { // static @Bean method beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(methodName); } else { // instance @Bean method beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(methodName); } beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); Autowire autowire = bean.getEnum("autowire"); if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); } String initMethodName = bean.getString("initMethod"); if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName); } String destroyMethodName = bean.getString("destroyMethod"); if (destroyMethodName != null) { beanDef.setDestroyMethodName(destroyMethodName); } // Consider scoping ScopedProxyMode proxyMode = ScopedProxyMode.NO; AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (attributes != null) { beanDef.setScope(attributes.getString("value")); proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } // Replace the original bean definition with the target one, if necessary BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) { BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); } if (logger.isDebugEnabled()) { logger.debug(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName)); } this.registry.registerBeanDefinition(beanName, beanDefToRegister); }
接下来,我们回到 AbstractApplicationContext#refresh
AbstractApplicationContext
refresh
finishBeanFactoryInitialization(beanFactory);
finishBeanFactoryInitialization
通过beanFactory来实例化我们之前交给它管理的BeanDefinition。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//省略一些代码
// 实例化一些单例(non-lazyinit)
beanFactory.preInstantiateSingletons();
}
DefaultListableBeanFactory
preInstantiateSingletons
实例化beanDefinitionNames中定义BeanDefinition的单例。当然也包含我们的BaigtAutoConfig中对应的@Bean(name="baigt")方法的BeanDefinition
public void preInstantiateSingletons() throws BeansException { // 从我们放入到beanDefinitionNames中来遍历进行实例化。 List beanNames = new ArrayList(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction() { @Override public Boolean run() { return ((SmartFactoryBean>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { // 最后执行这个方法进行实例化 getBean(beanName); } } } // SmartInitializingSingleton的处理 }
AbstractBeanFactory
getBean
public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
doGetBean
这里我们就是要创建单例的实例(有就从缓存中取)。创建的方式是通过ObjectFactory内部类实现中的createBean方法来完成。我们先看下getSingleton的逻辑。
// 首次进来为空 最后会走下边的逻辑 Object sharedInstance = getSingleton(beanName); // 通过this.beanDefinitionMap得到的 具体可自行查看源码。这里不太花篇幅讲述。 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //... if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { try { //最终创建Bean的逻辑 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //.... // 注意这里,会把单例cache起来,在后边可以直接使用 if (newSingleton) { addSingleton(beanName, singletonObject); }
DefaultSingletonBeanRegistry
getSingleton
这里我们要分析的核心逻辑(instance singleton)是调用的了ObjectFactory.getObject,即我们上边的内部类,而内部类的实现则是通过createBean完成。我们再来看下createBean的逻辑。
try { //回到了AbstractBeanFactory#doGetBean的ObjectFactory的getObject方法,执行其中的createBean方法 singletonObject = singletonFactory.getObject(); newSingleton = true; }
AbstractAutowireCapableBeanFactory
createBean
AbstractBeanFactory的子类实现方法
AbstractAutowireCapableBeanFactory#createBean(java.lang.Class) public T createBean(Class beanClass) throws BeansException { // Use prototype bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(beanClass); bd.setScope(SCOPE_PROTOTYPE); bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader()); return (T) createBean(beanClass.getName(), bd, null); }// 接上protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; Class> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { } // 普通Bean的实例创建 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
doCreateBean
核心关注instanceWrapper和exposedObject对象的处理过程
BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建bean实例的Wrapper对象 instanceWrapper = createBeanInstance(beanName, mbd, args); } // bean实例在wrapper中已经创建了(不完整) final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //省略一些代码。。。 // Initialize the bean instance. Object exposedObject = bean; try { // 注入property到Bean中 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } } //省略一些代码。。。 return exposedObject;
createBeanInstance
instanceWrapper = createBeanInstance(beanName, mbd, args); 该方法是给指定的name的Class创建Bean对象,支持无参、factoryMethod、AutoWireConstructor三种策略。默认执行无参的"instantiateBean"。而我们的BaigtAutoConfig中的@Bean则设置的有FactoryMethodName(我们定义的@Bean的方法名="env")
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. Class> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } //配置类中的@Bean方法是通过下边这种方式实例化的。 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } // 一般我们不是FactoryMethod和有参构造(也可以有哈) if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Need to determine the constructor... Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //没有特殊处理就使用无参构造实例 // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
instantiateUsingFactoryMethod
protected BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, Object[] explicitArgs) { return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); }
ConstructorResolver
instantiateUsingFactoryMethod
BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw);//。。。。Object beanInstance; beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse); bw.setBeanInstance(beanInstance); return bw;
SimpleInstantiationStrategy
instantiate
最后调用@Bean对应的方法的invoke方法。到此配置类中的@Bean已经实例化完成。
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Object factoryBean, final Method factoryMethod, Object... args) { try { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { ReflectionUtils.makeAccessible(factoryMethod); return null; } }); } else { ReflectionUtils.makeAccessible(factoryMethod); } Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get(); try { currentlyInvokedFactoryMethod.set(factoryMethod); //执行方法 return factoryMethod.invoke(factoryBean, args); } finally { if (priorInvokedFactoryMethod != null) { currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod); } else { currentlyInvokedFactoryMethod.remove(); } } } catch (IllegalArgumentException ex) { throws ex; } }
AbstractAutowireCapableBeanFactory
返回到doCreateBean方法
doCreateBean
我们继续看exposedObject处理的内容。装载Bean的Property属性,initBean对象。我们着重看下initializeBean方法。
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Object exposedObject = bean; try { //装载比如Property属性 可以是其他Bean对象,也可能是String等基本属性。具体见populateBean中的applyPropertyValues方法 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //初始化Bean对象 exposedObject = initializeBean(beanName, exposedObject, mbd); } }
initializeBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
初始化给定的Bean,(RootBeanDefinition为空时,执行BeanPost)执行wired的相关方法((BeanNameAware、BeanClassLoaderAware、BeanFactoryAware))、执行initMethod。比如InitializingBean#afterPropertiesSet();或者是自定义的init方法。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { //执行wire的method(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware) invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //执行init方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
invokeInitMethods
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods。执行afterPropertiesSet方法。如果是自定义的init方法,就调用invokeCustomInitMethod。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction() { @Override public Object run() throws Exception { ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
AbstractApplicationContext
返回到refresh方法
refresh
至此配置类相关的Bean实例化完成。
// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);