Spring Bean的生命周期以及IOC源码解析

IOC源码这一块太多只能讲个大概吧,建议还是去买本Spring IOC源码解析的书来看比较好,我也是自己看源代码以及视频整理的笔记

Bean的生命周期大概可以分为四个阶段,具体的等会再说,先看看IOC的源码吧

1、bean的创建

2、bean的属性赋值

3、bean的初始化

4、bean的销毁

IOC容器源码解析

我们创建容器以new AnnotationConfigApplicationContext(Config.class)为示例,我们点开源代码,看一下

其实做了挺多事的,在父类的的无参构造函数当中,就创建了一个BeanFactory的实例,其实可以去看一下这个类的无参构造函数,其实加载了很多必备的Bean到容器当中,例如之前提到过的一些常用的BeanPostProcessor,这里就不多说了,不然博客会太长了

接下来就是第一个方法register(componentClasses)解析配置类的注解,并且创建了BeanFactory的实例(org.springframework.beans.factory.support.DefaultListableBeanFactory的实例)并且将配置类注入到容器中

方法点进去之后能看到

 我们进到注册Bean的方法(BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);)里面

我们看一下是怎么注入的

其实就是将对象包装成BeanDefinition对象,然后添加到ConcurrentHashMap当中。

第二部,进入到refresh()方法,但是该方法位于父类的org.springframework.context.support.AbstractApplicationContext.class的515行,这个是一个刷新方法,将我们的业务Bean注入进去

无论是通过哪种创建Spring 的ioc容器都会执行这个refresh方法。大致的主要方法如下,不过有些方法的细节就不讲了,IOC过于庞大,懂个大概就差不多了,但是方法具体是干嘛的会一个一个讲

prepareRefresh()

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

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

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

obtainFreshBeanFactory()

获取到BeanFactory对象

prepareBeanFactory(beanFactory)

设置一下BeanFactory对象一些属性

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

         2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】

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

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

         5)、添加BeanPostProcessor【ApplicationListenerDetector】

         6)、添加一些loadTimeWeaver;

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

                   environment【ConfigurableEnvironment】、

                   systemProperties【Map<String, Object>】、

                   systemEnvironment【Map<String, Object>】

postProcessBeanFactory(beanFactory)

BeanFactory完成的后置工作,当前为空,但是可以继承当前类,在子类中可以实现这个方法

invokeBeanFactoryPostProcessors(beanFactory)

加载并执行BeanFactoryPostProcessor以及BeanDefinitionRegistryPostProcessor这两个接口的两个实现方法

1、postProcessBeanFactory()

2、postProcessBeanDefinitionRegistry():

这个方法里面做了很多加载,这里就不展示,自行去看源码吧

initMessageSource()

注册一个MessageSource的对象,但是这个Bean并没有加载到之前的那个Map当中,而是加载到一个缓存的Map当中,用于解决循环依赖

initApplicationEventMulticaster()

初始化一个派发器,跟上面那个差不多,只是对象不一样

onRefresh()

跟之前的那个postProcessorBeanFactory方法差不多,留给子类实现

registerListeners()

注册监听器,实现ApplicationListener<?>接口,并指定时在什么时候加载即指定ContextEvent

finishBeanFactoryInitialization(beanFactory)

这个就是加载所有业务单实例Bean的方法,并且生命周期都会在这里执行,首先会配置一些BeanFactory的一些属性,然后在加载业务Bean

第一部分优先获取Bean名称的一些定义信息getMergedLocalBeanDefinition(beanName),然后先处理实现FactoryBean的Bean

点进去getBean(beanName)之后,调用方法 doGetBean(name, null, null, false),这个方法就不贴截图了,代码太多不好截图,可以自己去对照这源码看,就讲调用了哪个方法就好了。

Object sharedInstance = getSingleton(beanName) 从缓存的Bean中去获取看看在不在,如果存在的话就直接获取(会去校验FactoryBean缓存中是否存在),不存在就执行else方法

如果缓存中不存在的话,就是一个新的Bean等待创建

运行到了markBeanAsCreated(String beanName),这个是用来标记当前beanName已经存在了,将beanName添加到alreadyCreated集合当中,然后运行到了下面

然后继续执行

进入到createBean()方法后,有个获取代理的方法,这个方法就得讲一下,跟Spring的AOP以及事务有关

Object bean = resolveBeforeInstantiation(beanName, mbdToUse)讲解:

我们点开查看一下这个方法,有个createProxy()创建代理方法

进入到创建代理的方法里面,我们看一下

我们点开getProxy方法,会返回一个createAopProxy().getProxy(classLoader);对象,我们依次点开后,在使用AOP到底是JDK动态代理还是CGLIB代理的关键所在

好了,代理的那个方法差不多了,我们改回到正题了

我们进入到Object beanInstance = doCreateBean(beanName, mbdToUse, args);

有个BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);这个是创建BeanWrapper的包装类,在createBeanInstance方法中最后会执行instantiateBean()

我们进入到这个instantiate(),最后有个BeanUtils.instantiateClass(constructorToUse)方法用来创建对象,这就不深入的讨论了,大家可以自己去看

然后包装一个BeanWrapperImpl对象,最后返回出去;创建好后,进行属性赋值以及Bean的初始化,在属性赋值的方法里面有个InstantiationAwareBeanPostProcessors方法执行

我们看下初始化方法

Bean的初始化,会先加载Aware,然后调用BeanPostProcessor的前置方法,然后加载初始化方法,再加载BeanPostProcessor的后置方法

这个方法基本就加载完了

finishRefresh()

加载完业务Bean的一些工作

resetCommonCaches()

这个是处于finally代码块的方法用来清除创建时临时缓存数据

Bean生命周期

在上面IOC分析里面已经提到了Bean的创建以及属性赋值了

接下来就是初始化以及销毁

初始化

初始化使用的方法有三种

1@Bean(initMethod = "")调用指定初始化方法

2、在类中设置@PostConstruct注解

3、实现InitializingBean接口,实现afterPropertiesSet()方法

销毁

对应的销毁也有三种

1、@Bean(destroyMethod= "")调用指定销毁方法

2、在类中设置@PreDestroy注解

3、实现DisposableBean接口,实现destroy()方法

销毁在容器关闭是时候执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB位运算基本使用以及位运算应用场景

最近在公司业务上用到了二进制匹配数据&#xff0c;但是MongoDB进行二进制运算&#xff08;Bitwise&#xff09;没用过&#xff0c;网上博客文章少&#xff0c;所以就上官网看API&#xff0c;因此记录一下&#xff0c;顺便在普及一下使用二进制位运算的一些应用。 在MongoDB的…

Mybatis源码日志模块分析

看源码需要先下载源码&#xff0c;可以去Mybatis的github上的仓库进行下载&#xff0c;Mybatis 这次就先整理一下日志这一块的源码分析&#xff0c;这块相对来说比较简单而且这个模块是Mybatis的基础模块。 之前的文章有谈到过Java的日志实现&#xff0c;大家也可以参考一下&…

python手机端给电脑端发送数据_期货交易软件有哪些比较好用?分手机端和电脑端...

一、电脑端交易软件期货电脑端交易软件目前市场上用的最多的是文华财经和博易大师&#xff0c;这两个软件都是免费交易使用的。从投资者使用角度来看&#xff0c;目前电脑端文华财经的评价比博易大师高一些。当然每个投资者有自己的使用习惯&#xff0c;博易大师也有自己优点&a…

Find the Difference(leetcode389)

2019独角兽企业重金招聘Python工程师标准>>> Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter that was added in …

Mybatis源码之数据源模块分析

先来看看java纯jdbc查询数据的示例&#xff1a; try {//加载对应的驱动类Class.forName("com.mysql.cj.jdbc.Driver");//创建连接Connection connection DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?serverTimezoneUTC", "roo…

Mybatis源码之缓存模块分析

缓存这个东西在很多应用中都能看到它们的身影&#xff0c;这次就讲讲在Mybatis中的缓存是怎么应用的&#xff0c;虽然说吧Mybatis中的缓存基本不怎么用&#xff0c;用的更多是第三方组件redis、MongoDB、MemCache等等。 Mybatis的缓存是基于Map实现的&#xff0c;从缓存中读写…

Mybatis源码之核心流程分析

终于谈到了Mybatis最核心的东西了&#xff0c;最核心的就是通过配置XML文件或注解中的SQL&#xff0c;直接调用接口就能执行配置好的SQL语句并封装成对应的返回类型的数据。 先看一下Mybatis使用示例&#xff1a; //创建Builder对象 SqlSessionFactoryBuilder builder new S…

Mybatis源码之与Spring集成包

这次讲讲Mybatis与Spring的整合&#xff0c;作为两款优秀的开源框架&#xff0c;被大众广泛使用&#xff0c;自然是需要强强联合的。 使用示例 先看一下怎么使用&#xff0c;首先需要引用这两款框架的jar包&#xff1a; <dependency>//spring-webmvc会自动去引入其他S…

Mybatis源码之插件模块分析

总结完这个Mybatis的整体主要功能基本上就差不多完&#xff0c;还有一些细节的部分&#xff0c;后续都会记录补充。 插件这个东西一般用的比较少&#xff0c;就算用的多的插件也算是PageHelper分页插件&#xff1b; PageHelper官网&#xff1a;https://github.com/pagehelper…

AMD推出7nm高端显卡Radeon VII,直指英伟达RTX 2080

显卡战争已经发展到了2019年&#xff0c;并且变得比任何人预想的都要激烈。 CES 2019大会上&#xff0c;AMD发布了第一款消费级的 7nm GPU&#xff0c;取名&#xff1a;Radeon VII。据了解&#xff0c;这不是 AMD 的第一颗 7nm 处理器&#xff08;早期以 AI 运算为主的 Radeon …

Spring集成Mybatis多数据源配置

既然在整理Mybatis那就把经常用的这个多数据源的笔记也整一下吧。 Spring集成Mybatis在之前就已经提到了。Spring集成Mybatis 集成Mybatis多数据源有两种方式&#xff1a; 1、创建多个SqlSessionFactory&#xff0c;扫描每个SqlSessionFactoryBean对应的包&#xff0c;形成了…

Spring文件上传

2019独角兽企业重金招聘Python工程师标准>>> Spring文件上传 1、所需依赖包&#xff1a;commons-fileupload-1.3.1.jar2、Maven配置文件pom.xml文件中加入依赖Jar包<dependency><groupId>commons-fileupload</groupId><artifactId>commons-…

算法题学到的一些小语言细节

1.要学会用i&#xff1b;可以简化很多代码&#xff1a;i&#xff1b;copyFromMe(i)&#xff1b;可以写成&#xff1a;copyFromeMe(i) 2.StringBuffer也跟列表一样有append函数&#xff1b; 3.if语句是分支不能进行循环&#xff0c;要写成while才能替代循环里面的判断 4. 这里的…

Zookeeper基础常用操作以及ACL权限

这次将Zookeeper的一些基础用法以及权限这块的都补充一下在这篇博客中。 上篇博客介绍了基于ZooKeeper实现的分布式锁&#xff0c;也介绍了一些ZooKeeper的节点类型以及监听机制&#xff0c;今天这里就不作过多的介绍了&#xff0c;大家也可以自行的去官方文档上看看更具体的介…

[中医经络学习一]足阳明胃经

人体有六脏&#xff08;心、肝、脾、肺、肾五脏&#xff0c;再加心包&#xff09;六腑&#xff08;胃、小肠、大肠、膀胱、胆、三焦&#xff09;&#xff0c;每个脏腑都联接着一条经络&#xff0c;一共12条经络&#xff0c;称“十二正经”&#xff0c;经络的走向在四肢两侧基本…

ThreadLocal原理解析以及是否需要调用remove方法

平常的开发过程中&#xff0c;如果有个类不是线程安全的&#xff0c;比如SimpleDateFormat&#xff0c;要使这个类在并发的过程中是线程安全的&#xff0c;那么可以将变量设置位局部变量&#xff0c;不过存在的问题就是频繁的创建对象&#xff0c;对性能和资源会有一定降低和消…

Maven基础及概念

前言 今天就来聊聊Maven的基础和一些比较概念性的东西&#xff0c;还有一些常用的Maven命令啥的&#xff0c;主要是某人脑子记不住&#xff0c;记在博客中让她自己看吧&#xff0c;省的费心给她找。 后续的文章会聊到Maven的一些比较高级用法&#xff0c;像自定义插件&#x…

Maven之pom.xml常用标签解析及镜像配置

前言 Maven仅仅是个打包工具而已&#xff0c;个人觉得没有太大必要花费在打包工具上&#xff0c;这里就列举一下个人觉得会常用标签的使用就好了&#xff0c;原理啥的基本就不太会去深度了解了&#xff0c;如果以后遇到需了解Maven工作原理的工作的话&#xff0c;到时候一定分…

Maven高级之插件开发

前言 终于来到了Maven的插件开发&#xff0c;其实Maven的插件并没有想象的那么难&#xff0c;刚开始讲Maven基础的时候就演示了一下JDK是如何打包的&#xff0c;Maven打包只是在JDK打包上封装了一层而已&#xff0c;Maven也支持自定义插件开发 创建 我们先使用quickstart原型…

Maven高级之archetype(原型/骨架)开发

前言 archetype这个的主要功能就是将写好的项目模块打包成一个原型&#xff0c;然后提供给其他人使用&#xff0c;这样别人就可以快速使用这个项目模板了。 这个东西虽然很多人都基本用不上&#xff0c;但原型这个东西用的好还是很方便的&#xff0c;能够在开发新项目上省去大…