1.Spring容器的创建会经历refresh()方法【创建刷新】(以AnnotationConfigApplicationContext为例)
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
2. refresh()会经历的过程:
//AbstractApplicationContext.java implement ConfigurableApplicationContext
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
3. prepareRefresh() 刷新前的预处理;

1)initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;

2)getEnvironment().validateRequiredProperties();检验属性的合法等

3)earlyApplicationEvents= new LinkedHashSet();保存容器中的一些早期的事件;

4.obtainFreshBeanFactory();获取BeanFactory;

1)refreshBeanFactory();刷新【创建】BeanFactory;

创建了一个this.beanFactory = new DefaultListableBeanFactory();

设置id;

2)getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;

3)将创建的BeanFactory【DefaultListableBeanFactory】返回;

5.prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置);

1)设置BeanFactory的类加载器、支持表达式解析器...

2)添加部分BeanPostProcessor【ApplicationContextAwareProcessor】

3)设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;

4)注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext

5)添加BeanPostProcessor【ApplicationListenerDetector】

6)添加编译时的AspectJ;

7)给BeanFactory中注册一些能用的组件;

environment【ConfigurableEnvironment】、

systemProperties【Map<String, Object>】、

systemEnvironment【Map<String, Object>】

AbstractApplicationContext.java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.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);
//... // Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//...
} // Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
//...
}
6.postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作;

子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

以上是BeanFactory的创建及预准备工作

7.invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法;

BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;

两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

执行BeanFactoryPostProcessor的方法;

  • 先执行BeanDefinitionRegistryPostProcessor

1)获取所有的BeanDefinitionRegistryPostProcessor;

2)看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、

postProcessor.postProcessBeanDefinitionRegistry>(registry)

3)在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;

postProcessor.postProcessBeanDefinitionRegistry(>registry)

4)最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;

postProcessor.postProcessBeanDefinitionRegistry>(registry)
  • 再执行BeanFactoryPostProcessor的方法

1)获取所有的BeanFactoryPostProcessor

2)看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、

postProcessor.postProcessBeanFactory()

3)在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;

postProcessor.postProcessBeanFactory()

4)最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;

postProcessor.postProcessBeanFactory()
8.registerBeanPostProcessors(beanFactory);

注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的

BeanPostProcessor、

DestructionAwareBeanPostProcessor、

InstantiationAwareBeanPostProcessor、

SmartInstantiationAwareBeanPostProcessor、

MergedBeanDefinitionPostProcessor【internalPostProcessors】

1)获取所有的BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级

2)先注册PriorityOrdered优先级接口的BeanPostProcessor;把每一个BeanPostProcessor;添加到BeanFactory中beanFactory.addBeanPostProcessor(postProcessor);

3)再注册Ordered接口的

4)最后注册没有实现任何优先级接口的

5)最终注册MergedBeanDefinitionPostProcessor;

6)注册一个ApplicationListenerDetector;用来在Bean创建完成后检查是否是ApplicationListener,如果是,则:

applicationContext.addApplicationListener((ApplicationListener<?>) bean);
9.initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);

1)获取BeanFactory

2)看容器中是否有id为messageSource的,类型是MessageSource的组件;如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;

MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;

3)把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;

beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);
10.initApplicationEventMulticaster();初始化事件派发器;

1)获取BeanFactory

2)从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;

3)如果上一步没有配置;创建一个SimpleApplicationEventMulticaster

4)将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入

11. onRefresh();留给子容器(子类)

子类重写这个方法,在容器刷新的时候可以自定义逻辑;

12. registerListeners();给容器中将所有项目里面的ApplicationListener注册进来;

1)从容器中拿到所有的ApplicationListener

2)将每个监听器添加到事件派发器中;

getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

3)派发之前步骤产生的事件;

13.finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean;

beanFactory.preInstantiateSingletons();初始化剩下的单实例bean; 实现类是DefaultListableBeanFactory.java

1)获取容器中的所有Bean,依次进行初始化和创建对象;

2)获取Bean的定义信息,即RootBeanDefinition;

RootBeanDefinition bd = >getMergedLocalBeanDefinition(beanName);

3)Bean不是抽象的,是单实例的,不是懒加载;

3.1)判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;

3.2)不是工厂Bean。利用getBean(beanName)创建对象;

3.2.0 getBean(beanName);等价于 ioc.getBean();

3.2.1

//AbstractBeanFactory.java
doGetBean(name, null, null, false);

3.2.2 先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)

从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);获取的

3.2.3缓存中获取不到,开始Bean的创建对象流程;

3.2.4标记当前bean已经被创建;

if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

3.2.5获取Bean的定义信息;

3.2.6【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】

//AbstractBeanFactory.java
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}

3.2.7启动单实例Bean的创建流程;

启动单实例Bean的创建流程如下所示:

1)createBean

//AbstractAutowireCapableBeanFactory.java重写了AbstractBeanFactory.java的createBean
createBean(beanName, mbd, args);

2)让BeanPostProcessor先拦截返回代理对象;

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

【InstantiationAwareBeanPostProcessor】:提前执行;

先触发:postProcessBeforeInstantiation();

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

如果有返回值:触发postProcessAfterInitialization();

if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}

3)如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)

4)创建bean

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

创建Bean:

1)【创建Bean实例】;createBeanInstance(beanName, mbd, args);

利用工厂方法或者对象的构造器创建出Bean实例;

2)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);

3)【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);-->AbstractAutowireCapableBeanFactory.java

赋值之前:

  	3.1)拿到InstantiationAwareBeanPostProcessor后置处理器;postProcessAfterInstantiation();

  3.2)拿到InstantiationAwareBeanPostProcessor后置处理器;postProcessPropertyValues();

开始赋值:

  	 3.3)应用Bean属性的值;为属性利用setter方法等进行赋值;
applyPropertyValues(beanName, mbd, bw, pvs);

4)【Bean初始化】initializeBean(beanName, exposedObject, mbd);

4.1)【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法

BeanNameAware\BeanClassLoaderAware\BeanFactoryAware

4.2)【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

result = beanProcessor.postProcessBeforeInit> > ialization(result, beanName);

4.3)【执行初始化方法】

invokeInitMethods(beanName, wrappedBean, mbd);
先判断是否是InitializingBean接口的实现;执行接口规定的初始化;

再判断是否自定义初始化方法;

4.4)【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization;

result = beanProcessor.postProcessAfterInitialization(result, beanName);

5)注册Bean的销毁方法;

//AbstractAutowireCapableBeanFactory.java
registerDisposableBeanIfNecessary(beanName, >bean, mbd);

5)将创建的Bean添加到缓存中singletonObjects;

ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息...;

所有Bean都利用getBean创建完成以后;

检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();

14.finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成;

1)initLifecycleProcessor();初始化和生命周期有关的后置处理器;

LifecycleProcessor默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有就new DefaultLifecycleProcessor();

加入到容器;

写一个LifecycleProcessor的实现类,可以在BeanFactory

                void onRefresh();
void onClose();

2)getLifecycleProcessor().onRefresh();

拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();

3)发布容器刷新完成事件;

publishEvent(new ContextRefreshedEvent(this));

4)liveBeansView.registerApplicationContext(this);

spring注解开发-容器创建全过程(源码)的更多相关文章

  1. spring注解开发-扩展原理(源码)

    1.BeanFactoryPostProcessor BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的; BeanFactoryPostProcesso ...

  2. 涨姿势:Spring Boot 2.x 启动全过程源码分析

    目录 SpringApplication 实例 run 方法运行过程 总结 上篇<Spring Boot 2.x 启动全过程源码分析(一)入口类剖析>我们分析了 Spring Boot 入 ...

  3. Spring Boot 2.x 启动全过程源码分析

    Spring Boot 2.x 启动全过程源码分析 SpringApplication 实例 run 方法运行过程 上面分析了 SpringApplication 实例对象构造方法初始化过程,下面继续 ...

  4. Spring Boot 2.x 启动全过程源码分析(上)入口类剖析

    Spring Boot 的应用教程我们已经分享过很多了,今天来通过源码来分析下它的启动过程,探究下 Spring Boot 为什么这么简便的奥秘. 本篇基于 Spring Boot 2.0.3 版本进 ...

  5. Spring注解驱动开发(六)-----spring容器创建【源码】

    Spring容器的refresh()[创建刷新] 1.prepareRefresh()刷新前的预处理 1).initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法 ...

  6. Spring Boot Dubbo 应用启停源码分析

    作者:张乎兴 来源:Dubbo官方博客 背景介绍 Dubbo Spring Boot 工程致力于简化 Dubbo | grep tid | grep -v "daemon" tid ...

  7. 浅尝Spring注解开发_AOP原理及完整过程分析(源码)

    浅尝Spring注解开发_AOP原理及完整过程分析(源码) 浅尝Spring注解开发,基于Spring 4.3.12 分析AOP执行过程及源码,包含AOP注解使用.AOP原理.分析Annotation ...

  8. Spring注解开发_Spring容器创建概述

    浅尝Spring注解开发_Spring容器创建概述 浅尝Spring注解开发,基于Spring 4.3.12 概述Spring容器创建的过程,包括12个方法的执行 浅尝Spring注解开发_自定义注册 ...

  9. Spring第四天,BeanPostProcessor源码分析,彻底搞懂IOC注入及注解优先级问题!

随机推荐

  1. Bid和Ask

    一直很懵到底哪个是哪个,记吧,很快就又懵了.网上又坑,每一个解释清楚的.这次搞明白了记下来. 当然,这么逗比的取名法我也是醉了.直接加点东西,UserBuy,UserSell,BankBuy,Bank ...

  2. C++经典面试题全集 50~100道 都附带有参考答案

    51.  引用与指针有什么区别? 答 .1) 引用必须被初始化,指针不必. 2) 引用初始化以后不能被改变,指针可以改变所指的对象. 3) 不存在指向空值的引用,但是存在指向空值的指针. 52.  描 ...

  3. HDU5145:5145 ( NPY and girls ) (莫队算法+排列组合+逆元)

    传送门 题意 给出n个数,m次访问,每次询问[L,R]的数有多少种排列 分析 \(n,m<=30000\),我们采用莫队算法,关键在于区间如何\(O(1)\)转移,由排列组合知识得到,如果加入一 ...

  4. UVA - 10817 Headmaster's Headache

    题目大意:有一些老师,每一位都有自己的工资以及教授的课程.共s<=8个课程.其中的一些老师必须选择,问你保证每节课至少有一个老师的最少总工资. 题解: 首先很容易想到状态压缩,搞一个3进制的数, ...

  5. YCOJ-DFS

    DFS搜索是搜索中的一种,即深度优先搜索(Depth First Search),其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次. 图示: 如图,这是邻接矩阵,我 ...

  6. Luogu P2278 [HNOI2003]操作系统【优先队列/重载运算符/模拟】 By cellur925

    题目传送门 本来是照着二叉堆的题去做的...没想到捡了个模拟...不过模拟我都不会...我好弱啊... 其实核心代码并不长,比辰哥的标程短到不知哪里去...但是思路需要清晰. 读题的时候我明白,当有优 ...

  7. Caffe实战四(Caffe可视化方法)

    面对一堆文件,一行行的数据,确实很难理解深度学习相关的概念,好比训练的数据.构建的网络是怎样的?今天按照书中第16天的内容实践了一翻,终于看到了所谓的深度神经网络的模样.(参考:<深度学习 21 ...

  8. CF850 E. Random Elections

    题目传送门:CF 题目大意: 现有\(A,B,C\)三人参加竞选,有n个市民对其进行投票,每个市民心中对三人都有一个优先顺序(如市民\(i\)对三人的优先顺序为\(A-C-B\),则凡是有\(A\)的 ...

  9. Vijos p1688 病毒传递 树形DP

    https://vijos.org/p/1688 看了下别人讨论的题解才想到的,不过方法和他的不同,感觉它的是错的.(感觉.感觉) 首先N只有1000, 如果能做到暴力枚举每一个节点,然后O(N)算出 ...

  10. Win10 隐藏盘符

    1.隐藏盘符 打开磁盘管理 -> 对要隐藏的盘符单击右键 -> 更改驱动器号和路径 -> 删除. 打开资源管理,已经看不到该盘符,该盘符已被隐藏.只是隐藏,该盘符上的数据仍然还在. ...