生命周期图解

生命周期举例

public class BeanLifeTest implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {private String name;public BeanLifeTest() {System.out.println("第一步:实例化类");}public void setName(String name) {System.out.println("第二步:设置属性");this.name = name;}@Overridepublic void setBeanName(String s) {System.out.println("第三步:设置bean的名称也就是spring容器中的名称,也就是id值" + s);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("第四步:获取工厂信息ApplicationContext");}//第五步执行初始化之前执行的方法@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("第六步:属性设置后执行的方法");}public void init() {System.out.println("第七步:执行自己配置的初始化方法");}//第八步执行初始化之后执行的方法public void start() {System.out.println("第九步:执行自身的业务方法");}@Overridepublic void destroy() throws Exception {System.out.println("第十步:执行spring的销毁方法");}public void myDestory() {System.out.println("第十一步:执行自己配置的销毁方法");}public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("testBeans.xml");String[] names = applicationContext.getBeanDefinitionNames();Arrays.stream(names).forEach(e -> System.out.println(e));BeanLifeTest beanLifeTest = (BeanLifeTest) applicationContext.getBean("testBean");beanLifeTest.start();((ClassPathXmlApplicationContext) applicationContext).close();}
}/*** @Description bean处理器*/
public class MyBeanPostProcessor implements BeanPostProcessor {//后处理bean,最重要的两步@Overridepublic Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {if(bean instanceof BeanLifeTest)System.out.println("第五步:初始化之前执行的方法");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String s) throws BeansException {if(bean instanceof BeanLifeTest)System.out.println("第八步:执行初始化之后的方法");return bean;}
}

ClassPathXmlApplicationContext原理

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {private Resource[] configResources;public ClassPathXmlApplicationContext() {}// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法public ClassPathXmlApplicationContext(ApplicationContext parent) {super(parent);}public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法setConfigLocations(configLocations);if (refresh) {refresh();  //重点!!!}}@Overrideprotected Resource[] getConfigResources() {return this.configResources;}
}@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 prepareRefresh();// 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 设置beanFactory类加载器,添加多个beanPostProcesserprepareBeanFactory(beanFactory);try {// 允许子类上下文中对beanFactory做后期处理postProcessBeanFactory(beanFactory);// 调用BeanFactoryPostProcessor各个实现类的方法invokeBeanFactoryPostProcessors(beanFactory);// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化registerBeanPostProcessors(beanFactory);//初始化ApplicationContext的MessageSourceinitMessageSource();//初始化ApplicationContext事件广播器initApplicationEventMulticaster();// 初始化子类特殊bean(钩子方法)onRefresh();// 注册事件监听器registerListeners();// 初始化所有singleton bean  重点!!重点!!finishBeanFactoryInitialization(beanFactory);// 广播事件,ApplicationContext初始化完成finishRefresh();
} catch (BeansException ex) {}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 初始化名字为conversionService的beanif (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// 初始化LoadTimeWeaverAware相关beanString[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// 停止使用临时类加载器进行类型匹配,置nullbeanFactory.setTempClassLoader(null);// 冻结(this.configurationFrozen = true;)所有beanDefinition,不让bean继续注册beanFactory.freezeConfiguration();// 实例化所有剩余的(非延迟-init)单例beanFactory.preInstantiateSingletons();
}//---------------------------------
// 实例化所有剩余的(非延迟-init)单例
public void preInstantiateSingletons() throws BeansException {// 拿到所有beanName 去遍历//获取所有beanList<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);// 触发所有非懒加载的singleton bean的初始化for (String beanName : beanNames) {//将非RootBeanDefinition转换为RootBeanDefinition以方便后续操作,//因为Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition//合并bean定义RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//如果当前“不是抽象类 && 是单例 && 不是延迟加载” 则执行if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) { //判断是否factoryBean//返回一个共享或独立的实例final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;// ......if (isEagerInit) {//返回一个实例getBean(beanName);}} else {getBean(beanName);}}}//...
}//进行实例bean的方法,调用getBean方法最后调到doGetBean
//-返回一个指定bean的实例,无论是共享或独立
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {//去掉beanName前的'&',然后再拿当前beanName去别名aliasMap.get(canonicalName)取final String beanName = transformedBeanName(name);Object bean;// 检查是否已创建过 ,并根据注册给定的名字返回singletonObject sharedInstance = getSingleton(beanName);//args为空时是获取bean,不为空是创建beanif (sharedInstance != null && args == null) { .........................//返回对象bean实例,如果是(beanInstance instanceof FactoryBean),则直接返回bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else {//检查当前bean是否已被创建,是则抛异常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 检查bean definition是否在该工厂已创建BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// 没找到就去找parent容器String nameToLookup = originalBeanName(name);if (args != null) {// 返回父容器(带参数)return (T) parentBeanFactory.getBean(nameToLookup, args);} else {// 不带参数return parentBeanFactory.getBean(nameToLookup, requiredType);}}//typeCheckOnly为true时,将指定的bean标记为已创建,添加进Set<String> alreadyCreated中if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {//合并bean定义final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);//检查是否Abstract,是则抛异常checkMergedBeanDefinition(mbd, beanName, args);// 获取依赖的bean名称String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {//然后遍历传入进行初始化for (String dependsOnBean : dependsOn) {//判断循环依赖if (isDependent(beanName, dependsOnBean)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");}registerDependentBean(dependsOnBean, beanName);//递归获取依赖的beangetBean(dependsOnBean);}    }// 接下来就到了创建一个bean实例的过程,创建单例/多例//单例模式bean创建if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);} catch (BeansException ex) {//。。。。。。。。。。。。。。。。}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}  else if (mbd.isPrototype()) {  //多例// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);} else {  //非单例/多例处理String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);} catch (IllegalStateException ex) {//...........}}} catch (BeansException ex) {// ...........}}// 检查所需的类型是否与实际bean实例的类型匹配。不是则抛出异常if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {try {return getTypeConverter().convertIfNecessary(bean, requiredType);} catch (TypeMismatchException ex) {.............}return (T) bean;}
}//AbstractAutowireCapableBeanFactory.createBean利会调用该方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {//......if (instanceWrapper == null) {//实例化bean,调用构造函数instanceWrapper = createBeanInstance(beanName, mbd, args);}//......// 保存单例的实例,解决循环依赖,此时bean还未注入属性boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}//......try {//填充bean ,如:bean属性,autowiredpopulateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {//初始化bean,调用初始化方法exposedObject = initializeBean(beanName, exposedObject, mbd);}//......
}
}protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
}//AbstractAutowireCapableBeanFactory.initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {//...} else {//调用一系列xxxAware接口,如:BeanNameAwareinvokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor的before接口wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//调用bean的初始化方法,InitializingBean.afterPropertiesSetinvokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {}if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor的after接口,后面讲到的AOP的实现的关键,就是在这里对bean进行包装的wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

Spring技术原理之Bean生命周期相关推荐

  1. spring一: 容器以及bean生命周期

    spring框架的几个优点: 1. 轻量级  2. 针对接口编程,解耦合   3. aop编程   4. 方便集成各种优秀框架  5.非侵入式   6.容器 IOC(Inversion of Cont ...

  2. Spring学习笔记八--Bean生命周期和后置处理器

    为什么80%的码农都做不了架构师?>>>    Bean生命周期和后置处理器 IOC容器的bean生命周期 1.构造器或工厂方法建立bean实例 2.bean属性赋值,引用其他bea ...

  3. Spring框架:三种Spring Bean生命周期技术

    当使用术语"生命周期"时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关. 在某些情况下,Bean生命周期的管理不是一件容易 ...

  4. 【Spring系列】- Bean生命周期底层原理

    Bean生命周期底层原理

  5. Spring IOC详解 以及 Bean生命周期详细过程 可以硬刚面试官的文章

    面试题 来自面试官发自灵魂深处的拷问:谈谈你对spring的理解: 一脸懵逼的求职者的内心活动:啥?  具体的问题是什么?现在的面试都不按套路出牌了吗?  抛出一个这么大的问题,你让我怎么回答? 一脸 ...

  6. 【Spring学习】Bean生命周期

    我理解的Bean生命周期包括两个方面: Bean何时创建,何时销毁 Bean从创建到销毁的执行流程 一.Bean创建与销毁 Bean的创建时机主要由几个配置项共同来决定,包括: scope属性,决定是 ...

  7. Spring Bean 生命周期之“我从哪里来”?懂得这个很重要

    Spring bean 的生命周期很容易理解.实例化 bean 时,可能需要执行一些初始化以使其进入可用 (Ready for Use)状态.类似地,当不再需要 bean 并将其从容器中移除时,可能需 ...

  8. 跟着小马哥学系列之 Spring IoC(源码篇:Bean 生命周期)

    跟着小马哥学系列之 Spring IoC(源码篇:Bean 生命周期) 简介 Bean 元信息来源 Bean 元信息解析成 BeanDefinition 并注册 BeanDefinition 转变成 ...

  9. 【Spring】- Bean生命周期

    2019独角兽企业重金招聘Python工程师标准>>> Spring Bean的生命周期: bean对象实例化 属性注入 beanfactory ApplicationContext ...

最新文章

  1. BeautifulSoup的初使用!
  2. HBase MetaStore和Compaction剖析
  3. php编译工具 知乎,关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解...
  4. 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
  5. 常用口语绝佳句型100句(2)
  6. HotSpot源码(二):Java与C语言对比
  7. php开启端口复用,请问下workman是否支持端口复用?
  8. python程序打包为exe可执行文件
  9. ICML2020 | 一行代码就能实现的测试集上分技巧
  10. 全国计算机一级考试网络知识,全国计算机等级考试一级网络基础知识复习题及答案.doc...
  11. 为Mac任意命令设置快捷键
  12. h5+js实现本地文件读取和写入-web前端教程
  13. python批量生成姓名_Python 批量生成中文姓名(百家姓)
  14. 【Maven】Idea搭建多Module项目修修补补
  15. Rundll32.exe使用方法大全
  16. 漏洞库:爬取CNVD-国家信息安全漏洞共享平台漏洞库
  17. amCharts 5.1.12 Crack
  18. Pannel DB支持定时文件、数据库备份、系统防御、监控告警、中间件安装
  19. 爬虫实践之非静态图片获取
  20. ucinet三天写论文!P1模型分析实战

热门文章

  1. 腾讯工程师也曾是个网瘾少年
  2. 波士顿动力的机器狗上班了!挪威石油公司还发其工号
  3. 数据挖掘学习笔记 5 线性回归知识及预测糖尿病实例
  4. 70. Climbing Stairs 题解
  5. azure夜校培训第5场 3月15日18:00---存储
  6. SQL Server安装问题程序被挂起的错误解决办法
  7. 江苏约谈滴滴、T3出行等6家企业 因疫情防控落实不到位
  8. 还要做手机?罗永浩称还完债就重返科技行业
  9. 英伟达正寻求欧盟批准其收购Arm
  10. 5年商标之争落幕 货拉拉夺回“货拉拉”商标权