https://blog.csdn.net/fuzhongmin05/article/details/73389779
Spring作为当前Java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解Spring Bean的生命周期是非常必要的。我们通常使用ApplicationContext作为Spring容器。这里,我们讲的也是 ApplicationContext中Bean的生命周期。而实际上BeanFactory也是差不多的,只不过处理器需要手动注册。
一、生命周期流程图:
我们知道一个对象的生命周期:创建(实例化-初始化)-使用-销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。
这里就实例化、初始化区别做一个说明,在Spring Bean中,实例化是为bean对象开辟空间(具体可以理解为构造函数的调用),初始化则是对属性的初始化,说的具体点,这里的属性初始化应该是属性的注入(构造函数也可以有属性的初始化语句,但不属于这一部分),属性注入是通过setter方法注入属性(不管是注解方式还是bean配置property属性方式,其实质都是通过属性的setter方法实现的)。
Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。
若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。
二、各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
IOC容器总得Bean生命周期
- Bean**实例**的创建
- 为Bean实例设置属性’
- 调用Bean的初始化方法
- 应用可以通过IOC容器**使用**Bean
- 当容器关闭时,调用Bean的销毁方法
三、演示
我们用一个简单的Spring Bean来演示一下Spring Bean的生命周期。
1、首先是一个简单的Spring Bean,调用Bean自身的方法和Bean级生命周期接口方法,为了方便演示,它实现了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口,同时有2个方法,对应配置文件中的init-method和destroy-method。
…
…
待补充
四、spring中的bean默认是单例模式
一、单例模式:在spring中其实是scope(作用范围)参数的缺省设定值
每个bean定义只生成一个对象实例,每次getBean请求获得的都是此实例
二、另一种和singleton对应的scope值—prototype多实例模式
调用getBean时,就new一个新实例
singleton和prototype的比较
singleton:
xml配置文件:
<bean id="dvdTypeDAO" class="com.terana.hibernate.impl.DvdTypeDAOImpl" />
测试代码:
ctx = new ClassPathXmlApplicationContext("spring-hibernate-mysql.xml");
DvdTypeDAO tDao1 = (DvdTypeDAO)ctx.getBean("dvdTypeDAO");
DvdTypeDAO tDao2 = (DvdTypeDAO)ctx.getBean("dvdTypeDAO");
运行:
true
com.terana.hibernate.impl.DvdTypeDAOImpl@15b0333
com.terana.hibernate.impl.DvdTypeDAOImpl@15b0333
说明前后两次getBean()获得的是同一实例,说明spring缺省是单例
prototype:
<bean id="dvdTypeDAO" class="com.terana.hibernate.impl.DvdTypeDAOImpl" scope="prototype" />
执行同样的测试代码
运行:
false
com.terana.hibernate.impl.DvdTypeDAOImpl@afae4a
com.terana.hibernate.impl.DvdTypeDAOImpl@1db9852
说明scope=”prototype”后,每次getBean()的都是不同的新实例
我们的bean(controller、service和Dao,实体bean除外)都是通过spring的IoC容器统一管理的,同时这些bean都是默认单例的,即一个bean在一个IoC容器中就只有一个实例。这一点跟设计模式中的单例略有不同,在单例模式中的单例是在整个应用中只有一个实例。
转载
https://blog.csdn.net/a327369238/article/details/52193822
https://www.cnblogs.com/zrtqsk/p/3735273.html