一文读懂 Bean的生命周期

 

目录

 前言:

一.什么是Bean的生命周期

 二.Bean的核心生命周期

 三.Bean的单例与多例模式

3.1.什么是单例与多例

3.2.单例与多例bean的生命周期

 3.3.单例与多例的演示

     好啦,今天的分享就到这了,希望能够帮到你呢!😊😊   


 前言:

日月更替,周而复始,大自然中的任何生命都有着它的周期,比如蚂蚁的寿命只有几年,而乌龟的寿命却有几十年甚至上百年。

同理,在Spring框架中,Bean对象也有着它的生命周期,然而对于Bean对象的生命周期,我们并不是很清楚,因为Spring帮助我们管理了Bean对象,所以,掌握Bean的生命周期,并知晓Spring在每个阶段为我们做了哪些事情是非常有必要的。

Spring Bean的生命周期,你了解吗!好啦那我们一起来了解Bean生命周期!!!

一.什么是Bean的生命周期

bean的生命周期指的是:bean创建-->初始化-->销毁 的过程,bean的生命周期由容器进行管理,我们可以自定义bean的初始化和销毁方法来满足我们的需求,当容器在bean进行到当前生命周期的时候,来调用自定义的初始化和销毁方法。

在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。

相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程:

  1.   Spring 对bean 进行实例化。
  2.   Spring 将值和bean的引用注入到bean对应的属性中。
  3.   如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()  方法。       (实现BeanNameAware清主要是为了通过Bean的引用来获得Bean的ID,一般业务中是很少有用到Bean的ID的
  4.   如果bean 实现了BeanFactoryAware接口,Spring将调用setBeanFactory() 方法,将BeanFactory容器实例传入。     (实现BeanFactoryAware 主要目的是为了获取Spring容器,如Bean通过Spring容器发布事件等
  5.   如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext() 方法,将bean所在的应用上下文的引用传入进来。

    (作用与BeanFactory类似都是为了获取Spring容器,不同的是Spring容器在调用setApplicationContext方法时会把它自己作为setApplicationContext 的参数传入,而Spring容器在调用setBeanDactory前需要程序员自己指定(注入)setBeanDactory里的参数BeanFactory )

  6.   如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization() 方法     (作用是在Bean实例创建成功后对进行增强处理,如对Bean进行修改,增加某个功能
  7.   如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用。
  8.   如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization() 方法。    (作用与6的一样,只不过6是在Bean初始化前执行的,而这个是在Bean初始化后执行的,时机不同 )
  9.   此时, bean 已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁。
  10.   如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

 二.Bean的核心生命周期

虽然spring提供了大量Bean级生命周期接口和容器级生命空间接口来扩展bean的生命周期,但bean的核心生命周期只有四个阶段:

1.实例化 Instantiation

doCreateBean中调用createBeanInstance() 方法

2.属性赋值 Populate

doCreateBean中调用populateBean() 方法

3.初始化 Initialization

doCreateBean中调用initializeBean() 方法

4.销毁 Destruction

对于scope=singleton的Bean (prototype不会触发销毁),当容器关闭时,会触发bean的销毁。

 三.Bean的单例与多例模式

3.1.什么是单例与多例

在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)
singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。
prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。
Spring bean默认是单例模式。

3.2.单例与多例bean的生命周期

  • 单实例下 bean的生命周期

容器启动——>初始化方法——>(容器关闭)销毁方法

  • 多实例下 bean的生命周期

容器启动——>调用bean——>初始化方法——>容器关闭(销毁方法不执行)

 3.3.单例与多例的演示

单例模式:

package com.junlinyi.beanLife;

import java.util.List;

public class ParamAction {
	private int age;
	private String name;
	private List<String> hobby;
	private int num = 1;

	public ParamAction() {
		super();
	}

	public ParamAction(int age, String name, List<String> hobby) {
		super();
		this.age = age;
		this.name = name;
		this.hobby = hobby;
	}

	public void execute() {
		System.out.println("this.num=" + this.num++);
		System.out.println(this.name);
		System.out.println(this.age);
		System.out.println(this.hobby);
	}
}

测试一手:

package com.junlinyi.beanLife;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/*
 * spring	bean的生命週期
 * spring	bean的單例多例
 *
 */
public class Demo2 {
	// 体现单例与多例的区别
	@Test
	public void test1() {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
		ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
		ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
		p1.execute();
		p2.execute();
		
//		单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
		applicationContext.close();
	}

}


spring配置文件:

<!--    bean的生命周期-->
    <bean id="paramAction" class="com.junlinyi.beanLife.ParamAction">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>

</beans>

 结果:

 由于我们默认使用的是单例模式,所以在运行时出现了变量污染,num值变为2 

 Bean工厂:

package com.junlinyi.beanLife;

public class InstanceFactory {
	public void init() {
		System.out.println("初始化方法");
	}

	public void destroy() {
		System.out.println("销毁方法");
	}

	public void service() {
		System.out.println("业务方法");
	}
}

测试一手:

package com.junlinyi.beanLife;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/*
 * spring	bean的生命週期
 * spring	bean的單例多例
 *
 */
public class Demo2 {
	// 体现单例与多例的初始化的时间点 instanceFactory
	@Test
	public void test2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
	}

}

spring配置上下文:

<bean id="instanceFactory" class="com.junlinyi.beanLife.InstanceFactory"
          scope="singleton" init-method="init" destroy-method="destroy"></bean>

  结果:

.单例模式中的JavaBean是跟着Spring上下文初始化的,容器生成对象跟着生成,容器死亡,对象死亡

多例模式:

将spring配置文件中指定scope为prototype

<bean id="paramAction" class="com.junlinyi.beanLife.ParamAction" scope="prototype">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>

    <bean id="instanceFactory" class="com.xissl.beanLife.InstanceFactory"
          scope="prototype" init-method="init" destroy-method="destroy"></bean>

 结果:

 多例模式走的Javabean是使用时才会创建,销毁要跟着Jvm走:

     好啦,今天的分享就到这了,希望能够帮到你呢!😊😊   

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值