这篇文章主要介绍“Spring IOC初始化执行流程是什么”,在日常操作中,相信很多人在Spring IOC初始化执行流程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring IOC初始化执行流程是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
运行环境:jdk8,springboot-2.2.2
Spring IOC容器的初始化核心在于AbstractApplicationContext
的refresh
方法
refresh方法执行的大体流程
获取到BeanFactory
并做一些BeanFactory
的准备工作
执行BeanFactory
的后置处理器
创建并注册其他的后置处理器
初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
初始化事件派发器,注册监听器
创建剩余的非懒加载的单实例bean
收尾工作。发布容器创建完成,清理一些缓存等
SpringBoot
下执行refresh()
方法的ApplicationContext
的实际类型是AnnotationConfigServletWebServerApplicationContext
关于AnnotationConfigServletWebServerApplicationContext
的结构请看这里
激活容器
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
创建早期的事件监听器和早期的事件
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
this.earlyApplicationEvents = new LinkedHashSet<>();
为 子类GenericApplicationContext
类的成员变量private final DefaultListableBeanFactory beanFactory
设置一个序列化ID
refreshBeanFactory();
this.beanFactory.setSerializationId(getId());
返回子类GenericApplicationContext
类的成员变量private final DefaultListableBeanFactory beanFactory
返回类型为ConfigurableListableBeanFactory
return getBeanFactory();
GenericApplicationContext
的beanFactory
是在创建上下文对象时就new了出来的
为beanFactory
进行了一些准备工作
设置了beanFactory
使用的类加载器,设置了用于解析表达式解析器(比如解析${}或#{}表达式的解析器)
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
添加了一些后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
设置了一些不能被自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
...
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
注册了一些能被自动装配的接口
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
...
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
补充:
ApplicationListenerDetector
的postProcessAfterInitialization(Object bean, String beanName)
在bean被创建实例化对象后执行
作用:如果此bean是ApplicationListener
,就执行this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
beanFactory.ignoreDependencyInterface
指定自动装配时忽略的接口
beanFactory.registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue)
指定自动装配的默认对象。
作用有点像@Primary
注解。
postProcessBeanFactory(beanFactory)
此方法为空方法,留给子类做实现。
执行两种后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
执行顺序
BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
BeanDefinitionRegistryPostProcessor
的postProcessBeanFactory
BeanFactoryPostProcessor
的postProcessBeanFactory
其中包含创建BeanDefinition的流程:
ConfigurationClassPostProcessor
的postProcessBeanDefinitionRegistry
方法会为主启动类所在包和子包中所有组件创建BeanDefinition
并 添加到DefaultListableBeanFactory
成员变量this.BeanDefinitionMap
中。
下面是扫描并获取到组件的方法栈
// 你可以在doScan方法中看到你basePackages(主启动类所在的包)下所有将要被创建BeanDefinition的组件
doScan:292, ClassPathBeanDefinitionScanner (org.springframework.context.annotation)
parse:132, ComponentScanAnnotationParser (org.springframework.context.annotation)
doProcessConfigurationClass:290, ConfigurationClassParser (org.springframework.context.annotation)
processConfigurationClass:245, ConfigurationClassParser (org.springframework.context.annotation)
parse:202, ConfigurationClassParser (org.springframework.context.annotation)
parse:170, ConfigurationClassParser (org.springframework.context.annotation)
processConfigBeanDefinitions:325, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:242, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support)
refresh:532, AbstractApplicationContext (org.springframework.context.support)
关于BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
和BeanFactoryPostProcessor
的postProcessBeanFactory
两个方法的区别
执行时机不不同。这两个方法上的注释是这样说的
postProcessBeanDefinitionRegistry
方法是在容器标准初始化完成后,bean定义信息(BeanDefinition
对象)未被加载,且未实例化任何bean时调用的。此时还可以向容器中添加新的或覆盖旧的bean定义信息
postProcessBeanFactory
方法是在容器标准初始化完成后,所有bean的定义信息已经被加载 ,但是还未实例化温和bean时调用的。执行时机要晚于postProcessBeanDefinitionRegistry
方法
向容器中添加后置处理器
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
向容器中添加一个后置处理器
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
分四类注册自定义的后置处理器
// 实现了PriorityOrdered接口
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 实现了PriorityOrdered接口,且是MergedBeanDefinitionPostProcessor类型
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 实现了Ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
// 没有实现PriorityOrdered或Ordered接口的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
先将后置处理器根据上述规则分类添加到不同的List中,再排序
再创建后置处理器的实例对象
再将实例对象添加到容器中(AbstractBeanFactory
的成员变量private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
)
向容器中添加一个后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
补充:
MergedBeanDefinitionPostProcessor
接口是用来在创建bean时做依赖注入的
initMessageSource()
初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
检查容器中是否有beanName == "messageSource"的bean。如果没有就new一个,并赋值给this.messageSource
,再将其添加到容器中
以后可注入此bean,执行其getMessage
方法获取到国际化配置文件中的内容
initApplicationEventMulticaster()
初始化事件派发器
检查容器中是否有beanName == "applicationEventMulticaster"的bean。如果没有就new一个,并赋值给this.applicationEventMulticaster
,再将其添加到容器中
onRefresh()
此方法为空方法,留给子类做实现。
将AbstractApplicationContext
的成员变量this.applicationListeners
事件监听器添加到事件派发器中
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
将容器中的事件监听器的名字添加到事件派发器中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
发布this.earlyApplicationEvents
早期事件,并清理掉早期事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
==创建剩下的非懒加载的单实例bean==
// 创建剩余的非懒加载单实例bean
finishBeanFactoryInitialization(beanFactory);
// 调用beanFactory创建剩余的非懒加载单实例bean
beanFactory.preInstantiateSingletons();
// 获取并遍历beanNames,用beanName获取BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
getBean(beanName);
doGetBean(name, null, null, false);
// 尝试从容器中获取bean,如果获取不到再自行创建bean。getSingleton方法为DefaultSingletonBeanRegistry的方法
Object sharedInstance = getSingleton(beanName);
// sharedInstance==null 执行以下流程创建bean
// 获取bean的定义信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 获取此bean所依赖的其他bean
String[] dependsOn = mbd.getDependsOn();
// 如果dependsOn不为空,遍历dependsOn,执行getBean(dep)。即,先创建此bean所依赖的bean。
if (dependsOn != null) {
for (String dep : dependsOn) {
getBean(dep);
}
}
// 如果此bean是单实例,执行以下方法创建bean
sharedInstance = getSingleton(beanName, () -> {
return createBean(beanName, mbd, args);
});
// 调用上面创建的匿名类实现的方法
singletonObject = singletonFactory.getObject();
// 调用上述的createBean(beanName, mbd, args);方法。创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// 创建并接收bean的实例对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 执行MergedBeanDefinitionPostProcessor类型的后置处理器。其中包含将@Autowired,@Value等信息放到injectionMetadataCache中的逻辑,之后执行的populateBean会从中取值,完成依赖注入
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// 赋值。其中包括依赖注入,为此bean的成员变量完成赋值
populateBean(beanName, mbd, instanceWrapper);
// 遍历调用InstantiationAwareBeanPostProcessor类型的后置处理器
ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName);
...
// 此过程包含AutowiredAnnotationBeanPostProcessor将@Autowired注解的对象注入到当前bean中
ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// 初始化。执行Aware接口方法,执行后置处理器,执行初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 如果实现了以下接口就执行BeanNameAware\BeanClassLoaderAware\BeanFactoryAware的接口方法
invokeAwareMethods(beanName, bean);
// 执行后置处理器的postProcessBeforeInitialization方法。其中包含执行@PostConstruct指定的初始化方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 执行初始化方法。先执行实现了InitializingBean接口的方法再执行@Bean指定的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 执行后置处理器的applyBeanPostProcessorsAfterInitialization方法。其中包含创建并返回aop代理对象的后置处理器
// 注册销毁方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
// 将bean添加到容器中
addSingleton(beanName, singletonObject);
所有Bean都利用getBean创建完成以后:
检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
到此,关于“Spring IOC初始化执行流程是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4455774/blog/4345039