指标
追踪上面一段代码的流程:
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等能力也曾经初始化实现
发表回复