spring中bean生命周期的初始化和销毁的几种方法详解

spring中bean生命周期的初始化和销毁的几种方法详解

最近在重新学习spring优秀的框架,顺便记录一下自己的总结,同时分享给大家。bean的生命周期指的是:bean创建–>初始化–>销毁 的过程,bean的生命周期由容器进行管理,我们可以自定义bean的初始化和销毁方法来满足我们的需求,当容器在bean进行到当前生命周期的时候,来调用自定义的初始化和销毁方法。今天主要讲解如何定义初始化和销毁的4中方法。

1,使用initMethod和destroyMethod

下面代码全部是通过配置类,而不是配置xml文件

Train.java

package cap5.bean;

public class Train {

	public Train() {
		// TODO Auto-generated constructor stub
		super();
		System.out.println("Train创建");
	}
	
	public void init() {
		System.out.println("train init...");
	}
	
	public void destroy() {
		System.out.println("train destroy");
	}
}

MainConfig.java

package cap5.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;

import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {

	@Bean(initMethod="init",destroyMethod="destroy")
	public Train train() {
		return new Train();
	}
	
	/*@Bean
	public Bike bike() {
		return new Bike();
	}*/
	
	/*@Bean
	public Jeep jeep() {
		return new Jeep();
	}*/
}

MainTest.java

package cap5.test;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import cap5.config.MainConfig;

public class MainTest {

	@Test
	public void test() {
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
		
		System.out.println("IOC 容器创建完成");
		System.out.println("IOC 容易准备关闭");
		/*String[] names = app.getBeanDefinitionNames();
		for(String name:names) {
			System.out.println("name="+name);
		}*/
		app.close();
		
	}
}

打印结果: 

spring中bean生命周期的初始化和销毁的几种方法详解

2,让bean实现InitializingBean和DisposableBean接口,然后分别实现afterPropertiesSet()方法和destroy()方法

afterPropertiesSet():从名字上就能看出,这个其实不是bean真正的初始化方法,而是在bean构建完成,设置好了属性之后调用的方法—–作用相当于初始化方法

destroy():当bean销毁时,会把单实例bean进行销毁

Bike.java

package cap5.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Bike implements InitializingBean,DisposableBean{

	public Bike() {
		// TODO Auto-generated constructor stub
		super();
		System.out.println("bike construct...");
	}
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("bike destroy");
	}

	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("bike init...");
		
	}

}

 MainConfig.java

package cap5.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;

import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {

	/*@Bean(initMethod="init",destroyMethod="destroy")
	public Train train() {
		return new Train();
	}*/
	
	@Bean
	public Bike bike() {
		return new Bike();
	}
	
	/*@Bean
	public Jeep jeep() {
		return new Jeep();
	}*/
}

MainTest.java和上面的一样,就不再贴上来了

测试结果:

spring中bean生命周期的初始化和销毁的几种方法详解

3,使用JSR250规则定义的注解来实现,JSR250的详细了解可自行百度,主要使用如下两个注解

@PostConstruct:从名字上也能看出这个注解的意思,就是在bean构建完成之后调用—相当于初始化

@PreDestroy:从名字上也能看出是在beandestroy之前会执行的被注解的方法—相当于销毁

Jeep.java

package cap5.bean;
import javax.annotation.*;

public class Jeep {

	public Jeep() {
		// TODO Auto-generated constructor stub
		super();
		System.out.println("jeep construct...");
	}
	
	@PostConstruct
	public void init() {
		System.out.println("jeep init...");
	}
	
	@PreDestroy
	public void destroy() {
		System.out.println("jeep destroy...");
	}
}

 MainConfig.java

package cap5.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;

import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {

	/*@Bean(initMethod="init",destroyMethod="destroy")
	public Train train() {
		return new Train();
	}*/
	
	/*@Bean
	public Bike bike() {
		return new Bike();
	}*/
	
	@Bean
	public Jeep jeep() {
		return new Jeep();
	}
}

 MainTest.java和上面一样,不重新贴了

运行结果:

spring中bean生命周期的初始化和销毁的几种方法详解

4,第四种方法是使用后置处理器,在bean初始化前后时会调用实现了BeanPostProcessor接口并重写两个方法,分别是:postProcessBeforeInitialization()postProcessAfterInitialization()方法

TaolongBeanPostProcessor.java

package cap5.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class TaolongBeanPostProcessor implements BeanPostProcessor {


	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("bean-----"+beanName+" init start...");
		return bean;
	}
	

	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		
		System.out.println("bean------"+beanName+" init end...");
		return bean;
	}
}

 Plane.java

package cap5.bean;

public class Plane {

	public Plane() {
		// TODO Auto-generated constructor stub
		System.out.println("plane construct...");
	}
	
}

 MainConfig.java

package cap5.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;

import cap5.bean.Bike;
import cap5.bean.Jeep;
import cap5.bean.Plane;
import cap5.bean.TaolongBeanPostProcessor;
import cap5.bean.Train;
//@ComponentScan(value= {"cap5.bean"},includeFilters= {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=TaolongBeanPostProcessor.class)})
@Configuration
public class MainConfig {

	/*@Bean(initMethod="init",destroyMethod="destroy")
	public Train train() {
		return new Train();
	}*/
	
	/*@Bean
	public Bike bike() {
		return new Bike();
	}*/
	
	/*@Bean
	public Jeep jeep() {
		return new Jeep();
	}*/
	@Bean
	public Plane plane() {
		return new Plane();
	}
	
	@Bean
	public TaolongBeanPostProcessor taolongBeanPostProcessor() {
		return new TaolongBeanPostProcessor();
	}
}

测试效果:

spring中bean生命周期的初始化和销毁的几种方法详解

上面都是默认情况下的单例的bean模式,加入在多个bean的情况下呢?容器如何管理bean的生命周期呢?

(1)当bean是多实例的模式下,bean不会在IOC容器创建的时候,去实例化bean,而是在真正使用该bean的时候实例化,这一点可以进行简单的测试一下,当增加@scope(”protorype“)时,就是多实例创建bean了

(2)当容器关闭的时候,多实例的情况下怎么处理,会不会将多个实例同时销毁呢?

我们来简单的测试一下:

MainConfig.java部分代码

@Scope("prototype")
	@Bean
	public Bike bike() {
		return new Bike();
	}

MianTest.java

package cap5.test;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import cap5.bean.Bike;
import cap5.config.MainConfig;

public class MainTest {

	@Test
	public void test() {
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
		System.out.println("IOC 容器创建完成");
		Bike bike1 = (Bike)app.getBean(Bike.class);
		Bike bike2 = (Bike)app.getBean(Bike.class);
		System.out.println(bike1==bike2);
		System.out.println("IOC 容易准备关闭");
		/*String[] names = app.getBeanDefinitionNames();
		for(String name:names) {
			System.out.println("name="+name);
		}*/
		app.close();
		
	}
}

 运行结果:

spring中bean生命周期的初始化和销毁的几种方法详解

这个结果证实了一下问题

1,多实例的时候bean不会随着IOC容器的构建而创建,而是在使用的时候创建的getBean()

2,多实例的时候,当容器进行关闭的时候,bean实例不会调用destroy方法,说明容器不控制多实例的销毁

3,多实例的情况下,返回的bean的对象时不一样的,返回为false

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111239.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • IDEA中使用eclipse快捷键「建议收藏」

    IDEA中使用eclipse快捷键「建议收藏」1.修改使用Eclipse风格的快捷键目的是习惯了使用eclipse的快捷键,在使用IDEA时不想重头记一套新的快捷键。按照下面的顺序操作File–>settings–>keymap–>在下来框中选中Eclipse选择Apply保存设置这样改完就是elipse风格的快捷方式了2.单独设置一部分比较主要的与eclipse中不一致的操作2

  • ubuntu 卸载命令_强制卸载电脑软件

    ubuntu 卸载命令_强制卸载电脑软件Ubuntu命令卸载软件_李柏林的博客-CSDN博客_ubuntu卸载程序1.打开一个终端,输入dpkg–list,按下Enter键,终端输出以下内容,显示的是你电脑上安装的所有软件。2.在终端中找到你需要卸载的软件的名称,列表是按照首字母排序的。3.在终端上输入命令sudoapt-get–purgeremove包名(–purge是可选项,写上这个属性是将软件及其配置文件一并删除,如不需要删除配置文件,可执行sudoapt-getr…https://blog.csdn.net/

  • Java中Hashtable和HashMap区别「建议收藏」

    Java中Hashtable和HashMap区别「建议收藏」第一,继承不同。

  • mac idea 2021激活码【2021免费激活】

    (mac idea 2021激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSWQi…

  • 针不戳,数据库性能优化八大方案。[通俗易懂]

    针不戳,数据库性能优化八大方案。[通俗易懂]毫不夸张的说咱们后端工程师,无论在哪家公司,呆在哪个团队,做哪个系统,遇到的第一个让人头疼的问题绝对是数据库性能问题。如果我们有一套成熟的方法论,能让大家快速、准确的去选择出合适的优化方案,我相信能够快速准备解决咱么日常遇到的80%甚至90%的性能问题。从解决问题的角度出发,我们得先了解到问题的原因;其次我们得有一套思考、判断问题的流程方式,让我们合理的站在哪个层面选择方案;数据库的优化方案核心本质有三种减少数据量、用空间换性能、选择合适的存储系统。这也对应了开篇讲解的慢的三个原因https。…

  • Windows Server服务器上DNS服务器配置方法[通俗易懂]

    Windows Server服务器上DNS服务器配置方法[通俗易懂]图解WindowsServer服务器上DNS服务器配置 本篇经验将和大家介绍WindowsServer服务器上DNS服务器配置的步骤,希望对大家的工作和学习有所帮助!DNS服务器安装 1  打开“添加角色”,安装DNS服务。点击下一步,安装,开始启动dns服务器进行配置,如下图所示: 2 首先配置dns服务器,如下图所示: 3  进…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号