一个Spring Bean从无到有的过程
有开头没结尾
经历了java开发变迁史,从早期编写原生的servlet、自研mvc和jdbc工具、和使用开源框架struts、hibernate、jsp、spring、springmvc、freemarker、springboot,到最后前后端分离式开发,一开始开发工具用的是editplus。相对来说,现在开发很好了,框架生态(只有spring生态传承下来了,其他都成了历史)。到spring生态圈终结了,它的体系太过庞大了,席卷了各国,项目产品技术换型的几率很小了。
一开始做Spring相关开发,写了大量xml配置,到后来换成了注解式开发,虽然能干活,可并不知道它的内在原理和设计理念是什么,随着时间的累计,需要做sping 扩展或集成,就要研究源码级是如何实现的了。我就以一个Spring Bean如何创建开始,不要小看一个Bean,很多码农都说不清它的创建过程。
简单介绍Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于JEE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
就是图片里的Beans,下面开始进入正题,看仔细了,这很重要
介绍bean之前,说下ioc和context上下文(可以理解为一个宿主环境)
ioc是Inversion of Control的简称,行内话叫控制反转,早期开发都是需要对象,自己new出来一个,可有了ioc后,我们不需要
自己new对象了,让spring ioc容器负责对象的创建和管理。一句话概括ioc的作用颠倒了对象的依赖关系,ioc容器管理对象。
尽量搞明白bean,ioc,context,对以后学spring生态很重要。
Spring bean 分两种,一种普通bean,一种是工厂型的bean,但处理类型很多
一, 普通bean(以xml配置为例,现在改用注解的人越来越多了)
准备好原材料
spring-bean.xml文件(以演示为例)
User.java
测试类
输出结果
解析初始化过程,就从这行代码
说起,看看spring做了多少事
三大阶段:bean解析,bean实例化,bean初始化,销毁
1. bean解析定义注册阶段
早期开发人员都知道,配置文件以xml文件(现在人都喜欢注解解析了)居多,要把xml文件内容解析成java对应的类,简称dom解析,如
spring也是如此,一开始进行大量的xml文件解析工作,和java对应的类映射好
这只是一个bean定义(开发过程时有很多很多个Bean定义注册),很重要做那么多工作就是为了组装成这种数据结构:this.beanDefinitionMap.put(beanName, beanDefinition);它是这么定义的:
beanDefinition的部分属性,把它当然一种组装数据的结构就行
2. Bean实例化和初始化阶段
调用时
preInstantiateSingletons核心代码:
0:DefaultListableBeanFactory(AbstractBeanFactory).getBean(String)
1 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 303
2 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String) line: 231 ,第一次getSingleton
3 Object org.springframework.beans.factory.support.AbstractBeanFactory.createBean(String beanName, RootBeanDefinition mbd, Object[] args)
要分叉了:
4. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
判断是否有InstantiationAwareBeanPostProcessor,applyBeanPostProcessorsBeforeInstantiation()>postProcessBeforeInstantiation(),
applyBeanPostProcessorsAfterInitialization()>postProcessAfterInitialization().
返回代理对象的机会,一旦返回,就没有下面的事了,aop代理由此可生
如果return ,直接跳到10阶段
5 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, 4 RootBeanDefinition mbd, Object[] args) 很重要
6 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args), 实例化完成,详细请继续看源码,注意实例化策略方式不止一种:构造器,工厂方法,也有机会通过cglib
cglid代理
7 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(beanName, mbd, instanceWrapper),,详细请继续看源码,下面是部分
此阶段也有机会产生分叉,特别是实现了InstantiationAwareBeanPostProcessor,提前返回,不再进行后续的autowireByName,autowireByType和属性赋值操作,但并不影响初始化操作
8 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(String beanName, Object bean, RootBeanDefinition mbd),初始化完成
10 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory),第二次getSingleton,但实现方法不一样
注意篇幅有限: 列了一些核心方法,其实还有很多,由于代码量超超多,就不贴了
工厂型bean
该Bean实现了FactoryBean接口
它和上面没有实现FactoryBean接口的处理方式不太一样,大体上相同不再赘述
顺序图:
3. bean销毁
三种体现:
3.1 和初始化InitializingBean对应的DisposableBean接口,
3.2 自定义方法,destroy-method="destroyXML"
3.3 和@PostConstruct对应的 @PreDestroy
销毁顺序如图
代码就不举例了。
总结:其实你可以new User(6,"dongguangmming",99),但和spring没关系,Spring很强大,各个阶段都有机会改造参与bean的过程,组合度也很高,****BeanDefinitionRegistryPostProcessor,***BeanPostProcessor,***BeanFactory,****BeanFactoryPostProcessor
记住Spring bean:解析注册,实例化,初始化,销毁,才能做扩展性开发或集成第三方组件(比如mybatis,dubbo,email,zk,redis等)到spring的生态圈里
参考:
0 Spring 框架简介 https://www.ibm.com/developerworks/cn/java/wa-spring1/
1. spring bean是什么 https://www.awaimai.com/2596.html
2 what-in-the-world-are-spring-beans https://stackoverflow.com/questions/17193365/what-in-the-world-are-spring-beans
3. Spring Bean Lifecycle https://www.benchresources.net/spring-bean-lifecycle/
4. Detailed tutorial on Redis caching in the SpringBoot series https://laptrinhx.com/detailed-tutorial-on-redis-caching-in-the-springboot-series-3352915639/
5. Spring Bean creation process http://www.programmersought.com/article/55942589567/
6. Inversion of Control Containers and the Dependency Injection pattern https://martinfowler.com/articles/injection.html