共计 28242 个字符,预计需要花费 71 分钟才能阅读完成。
指标
追踪上面一段代码的流程:
AnnotationConfigApplicationContextDemo
/**
* description
* date 2021-06-30 11:21
**/
public class AnnotationConfigApplicationContextDemo {
public static void main(String[] args) {final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SimpleConfig.class);
User user = applicationContext.getBean(User.class);
System.out.println("user:" + user);
}
}
Configuration
public class SimpleConfig {
Bean
public User user(){return new User("xgimi", 10);
}
}
public class User {
private String name;
private Integer age;
…
流程
外围逻辑都在 AnnotationConfigApplicationContext 的带参结构器中:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();
register(componentClasses);
refresh();}
空结构器做了什么
先说答案:两个事件,一是创立了 BedefinitionReader、BeanDefinitionScanner,提供了扫描 BeanDefinition 的能力;二是通过父类 GenericApplicationContext 的结构器创立了 DefaultListableBeanFactory,提供底层的 IOC 能力。
初始化 AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 注入 registry,并且初始化 Environment 对象
this(registry, getOrCreateEnvironment(registry));
}
提供注册 beanDefinition 的能力
public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
咱们会在前面探索 BeanDefinitionRegistry 注册 BeanDefinition 的实质
获取环境对象 getOrCreateEnvironment 这个办法进行页游的外部环境的创立并获取:
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {return ((EnvironmentCapable) registry).getEnvironment();}
return new StandardEnvironment();}
环境对象中蕴含了零碎环境变量,自定义属性等内容。
通过结构器能够看到,AnnotatedBeanDefinitwww.sangpi.comionReader 底层保护了一个 BeanDefinitionRegistry。实际上,他就是通过 BeanDefinitionRegistry 提供的注册能力,而 AnnotationConfigApplicationContext 自身就是一个 BeanDefinitionRegistry;所以在调用 AnnotatedBeanDefinitionReader 结构器时,咱们传入的就是 AnnotationConfigApplicationContext:
实际上是组合关系,AnnotationConfigApplicationContext 中大部分的能力,包含注册 beanDefinition,依赖查找,依赖注入,都是通过 DefaultListableBeanFactory 通过的底层能力反对。
如何将配置类注册为 BeanDefinition
在 AnnotationConfigApplicationContext 中:
Override
public void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
// 注册配置类
this.reader.register(componentClasses);
registerComponentClass.end();}
从下面代码能够看出,次要是调用了 reader 的 register 办法实现的注册,来看下这个办法的实现逻辑
public void register(Class<?>... componentClasses) {for (Class<?> componentClass : componentClasses) {registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {doRegisterBean(beanClass, null, null, null, null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 进来就先把 class 对象转为一个 BeanDefinition,此时这个 BeanDefinition 中只有 class 信息和注解类上注解信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 解决 @Conditional 注解
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}
//supplier 会优先于所有的结构器和工厂办法进行类的实例化,然而不会影响属性设置
abd.setInstanceSupplier(supplier);
// 解决 scope,没有设置,默认返回 singleton;@Scope("scopeName")会在这个办法中进行解决,取得 scopeName
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 创立 beanName AnnotationBeanNameGenerator 提供能力,但以接口入参为优先
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 将以下几个注解标注的值设置到 abd 中
//1.@Lazy 2.@Primary 3.@Role 4.@DependesOn 5.@Description
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));
}
}
}
if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);
}
}
//definitionHolder 保留的是 beanDefinition 和 beanName(还能够有别名)
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 如果 @Scope 设置了代理,这里将会返回一个代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 将 definitionHolder 中的 beanDefinition 注册到 registry 对象中
//DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
// 最初的后果:DefaultListableBeanFactory 中的 beanDefinitionMap 中存入一个 beanDefinition,beanDefinitionNames 中存入 beanName
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
综合上述代码,整顿以下 doRegisterBean 的大抵逻辑:
创立一个配置类对象的 AnnotationBeanDefinition
通过 AnnotationBeanDefinition 解析类下面是否存在 Conditional 注解,并判断是否满足注册的条件,如果不满足,则不进行注册
向 abd 中注册办法入参传入的 Supplier,后续可通过该接口实现 bean 的实例化
解析 Scope 属性并注册到 abd 中
创立 beanName
创立一个 beanDefinitionHolder 保留 abd 和 beanName,alias 之间的对应关系
解决非单例 Scope,返回一个代理,详见 Scope 的处理过程
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
咱们来看下第 9 步,到底是如何注册的:
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
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) {
//TODO
registry.registerAlias(beanName, alias);
}
}
}
能够看到,理论进行了两局部注册:
注册 beanName
注册别名
后果发现还是应用的 DefaultListableBeanFactory 进行注册的,这也论证了咱们下面对于 DefaultListableBeanFactory 和 AnnotationConfigApplicationContext 之间关系的论断。来看看 DefaultListableBeanFactory 中到底是怎么实现的吧:
@Override
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 existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean'" + beanName +
"'with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean'" + beanName +
"'with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean'" + beanName +
"'with an equivalent definition: replacing [" + existingDefinition +
"] 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<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {// Still in startup registration phase
// 次要看这里
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {clearByTypeCache();
}
}
上述的代码,先查看了容器中是否曾经注册过了该 bd,再查看了是否正在注册该 db;而咱们是第一次注册,所以走的外围分支就是第 59 行开始的 else 分支。做了上面几件事件:
向 beanDefinitionMap 中放入了 beanName 为 key 的 beanDefinition
向 beanDefinitionNames 中放入了 beanName
如果 manualSingletonNames 中存在 beanName,将其移除
为什么要独自保护一个 beanDefinitionNames?次要是因为 beanDefinitionMap 是无序的,而 beanDefinitionNames 是一个 ArrayList,是有序的,能够保留 bd 的注册程序
refresh 办法都做了什么
1.prepareRefresh
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing" + this);
}
else {logger.debug("Refreshing" + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 非 web 环境下默认是空的实现
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();}
预刷新阶段次要做了一下几件事件:
提供 initPropertySources()扩大办法供容器进行内部资源加载,在 AnnotationContextApplicationContext 中默认是空实现
getEnvironment().validateRequiredProperties(); 进行必填属性的校验,是 AbstractPropertyResolver 这个接口提供的能力,Environment 对象是这个接口的实现。
@Override
public void validateRequiredProperties() {MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {if (this.getProperty(key) == null) {ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {throw ex;}
}
默认容器中是没有必须存在的属性的,如果须要增加该校验,则通过 beanFactory 获取到 Environment,而后再进行设置:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(SimpleConfig.class);
applicationContext.getEnvironment().setRequiredProperties("system");
applicationContext.refresh();
实际上是调用的 AbstractPropertyResolver 类的上面办法
// 设置必须存在的属性
@Override
public void setRequiredProperties(String... requiredProperties) {Collections.addAll(this.requiredProperties, requiredProperties);
}
requiredProperties 是一个 LinkedHashSet
private final Set<String> requiredProperties = new LinkedHashSet<>();
在容器中创立 earlyApplicationListeners、earlyApplicationEvents
2.obtainFreshBeanFactory
通过该办法的返回值能够判断他就是获取了容器中内置的 ConfigurableListableBeanFactory,咱们来看他具体是怎么获取的:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();
return getBeanFactory();}
其中:getBeanFactory()办法是很好了解的,他就是把 GenericApplicationContext 中保留的 DefaultListableBeanFactory 返回,这个 DefaultListableBeanFactor 是在 GenericApplicationContext 的空结构器中实例化的。咱们看下 refreshBeanFactory()中做了什么:
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
// 外部容器只容许 refresh 一次
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call'refresh'once");
}
this.beanFactory.setSerializationId(getId());
}
次要是对 refreshed 进行了 cas 批改,以保障容器只会被刷新一次
3.prepareBeanFactory(beanFactory)
容器的筹备阶段
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {// 设置 el 表达式解析器(#{...})beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 设置属性解析器 PropertyEditorRegistrar
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 为容器中增加一个 ApplicationContextAwareProcessor,这是容器中增加的第一个 BeanPostProcessor
//ApplicationContextAwareProcessor 的作用:// 判断 bean 是否实现了上面的 Aware 接口,如果实现了,这把相应的内建 bean 或单例对象赋给该 bean
//1.EnvironmentAware -> applicationContext.getEnvironment()
//2.EmbeddedValueResolverAware -> embeddedValueResolver
//3.ResourceLoaderAware -> applicationContext
//4.ApplicationEventPublisherAware -> applicationContext
//5.MessageSourceAware -> applicationContext
//6.ApplicationContextAware -> applicationContext
//7.ApplicationStartupAware -> applicationContext.getApplicationStartup()
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// 增加容器内建依赖
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 解决实现了 ApplicationListener 接口的 bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 在 beanFactory 中注入上面的单例对象
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
设置 ClassLoader
设置 el 表达式解析器
设置 PropertyEditorRegistrar
增加一个 ApplicationContextAwareProcessor 判断 bean 是否实现了上面的 Aware 接口,如果实现了,这把相应的内建 bean 或单例对象赋给该 bean 1.EnvironmentAware -> applicationContext.getEnvironment() 2.EmbeddedValueResolverAware -> embeddedValueResolver 3.ResourceLoaderAware -> applicationContext 4.ApplicationEventPublisherAware -> applicationContext 5.MessageSourceAware -> applicationContext 6.ApplicationContextAware -> applicationContext 7.ApplicationStartupAware -> applicationContext.getApplicationStartup()
ignoreDependencyInterface:在主动拆卸时疏忽上面这些接口,实现了下述接口,能够通过 set 办法承受 aware 回调传入的值进行拆卸
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
增加容器内建依赖。容器的内建依赖会保留在 resolvableDependencies,反对通过类型进行依赖注入,次要解决的问题是同一种类型存在多个依赖对象,spring 在主动拆卸的时候会报错,然而如果在 resolvableDependencies 中指定了具体类型的拆卸对象,则间接能够应用指定对象。spring 容器中存在多个 BeanFactory 等类型的对歌对象,所以这里将其依赖对象指定,防止报错。咱们也能够通过自定义 BeanFactoryPostProcessor 获取 Beanfactory,而后指定本人的类型 - 依赖对象关系。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
增加 ApplicationListenerDetector,DestructionAwareBeanPostProcessor:bean 曝光前回调,在对外提供 bean 实例之前,能够返回代理对象替换 beanMergedBeanDefinitionPostProcessor
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
间接注册四个单例对象
// Register default environment beans.
// 在 beanFactory 中注入上面的单例对象
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
4.postProcessBeanFactory
预留的扩大办法,默认没有实现
5.invokeBeanFactoryPostProcessors(beanFactory)
对于 BeanFactoryPostProcesso,咱们先理解上面两点:
注册 BeanFactoryPostProcessor:ConfigurableApplicationContext#addBeanFactoryPostProcessor
BeanFactoryPostProcessor 的作用:
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 在所有 beanDefinition 曾经加载,且没有 Bean 实例化之前,批改 application 的内置 beanFactory
* 该办法能够反对批改 beanDefinition 的属性配置,甚至能够提前初始化 bean
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
简而言之,就是在第 3 步将内置 beanfactory 筹备结束之后。给用户一次机会再获取到 beanFactory 接下来咱们钻研 invokeBeanFactoryPostProcessors 的流程,这里默认容器中是不会注册 BeanFactoryPostProcessor 的,然而这个办法还有其余的作用
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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
getBeanFactoryPostProcessors()
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {return this.beanFactoryPostProcessors;}
PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// %3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
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, beanFactory.getApplicationStartup());
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<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> 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<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
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();}
次要流程:
创立两个 list 别离保留 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor
将自定义注册的 BeanFactoryPostProcessor 依照类型别离存入 regularPostProcessors 或者 registryProcessors,并且:如果是 BeanDefinitionRegistryPostProcessor,则间接调用其 postProcessBeanDefinitionRegistry 办法
创立一个新的列表来保留容器内置的 BeanDefinitionRegistryPostProcessor
通过 BeanDefinitionRegistryPostProcessor 类型以及 PriorityOrdered 获取容器中对对应的 bean,放入 currentRegistryProcessors,并将名字放入 processedBeans,示意曾经执行。这里会失去一个:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
将 currentRegistryProcessors 排序,并且放入 registryProcessors
遍历执行 currentRegistryProcessors 中的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 办法
这里会执行 internalConfigurationAnnotationProcessor 的回调办法,这个类后续会专项钻研,其后果就是把配置类中 Bean 办法对应的类加载到容器中注册为 bd
清空 currentRegistryProcessors
反复 4 -8,调用的是实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor
反复 4 -8,调用没有实现排序接口的 BeanDefinitionRegistryPostProcessor
通过下面的操作,所有的 BeanDefinitionRegistryPostProcessor 都退出了 registryProcessors,所有的自定义 BeanFactoryPostProcessor 都退出了 regularPostProcessors。执行他们的 postProcessBeanFactory 办法
当初还有容器内置的 BeanFactoryPostProcessor 没有解决,也依照 PriorityOrdered,Ordered,nonOrdered 的程序顺次加载并调用他们的 postProcessBeanFactory 办法
6.initMessageSource
MessageSource 列为专题讨论
7.initApplicationEventMulticaster()
事件播送机制列为专题讨论
8.onRefresh
截止到这里,整个 beanfactory 曾经准备就绪了。剩下的就是容器中的 bean 的解决了,再此之前,能够通过 onFresh 办法执行回调。例如在 SpringBoot 中,就是通过这个办法进行的嵌入式 web 容器启动
9.registerListeners()
注册容器内置的 listener
注册实现了 ApplicationListener 接口的类
10.inishBeanFactoryInitialization(beanFactory)
实例化所有非懒加载的单例 bean 这个流程又是非常复杂的逻辑,咱们放在第二章进行探讨
总结
通过上述的步骤,spring 容器曾经初始化实现,beanFactory 准备就绪。ApplicatiionContext 提供的扩大个性:事件机制,资源,AOP 等能力也曾经初始化实现