三种方式创建bean对象在springIOC容器中初始化、销毁阶段要调用的自定义方法
1. 使用@Bean注解定义initMethod和destroyMethod
所谓initMethod和destroyMethod,是指在springIOC容器中,对于bean对象执行到初始化阶段和销毁阶段所调用的方法,其并不是初始化方法和销毁方法本身。
对于单例模式,initMethod会在创建容器时,构造方法、属性赋值方法完成之后调用,destroyMethod会在关闭容器之后调用;
对于原型模式,initMethod会在每次获取bean对象时,构造方法、属性赋值方法完成之后调用,而destroyMethod则不会调用,换句话说,对于多实例bean,springIOC容器只负责创建,不负责销毁。
/**
* 使用@Bean注解的方式定义initMethod和destroyMethod
* initMethod方法:
* 是springIOC容器执行到初始化bean对象阶段时调用的方法,并不是初始化bean对象方法本身
* 对于单实例模式,是在创建容器之后执行,只执行一次
* 对于多实例模式,是在获取bean对象时执行,每获取一次,则执行一次
* destroyMethod方法:
* 是springIOC容器执行到销毁bean对象阶段时调用的方法,并不是销毁bean对象方法本身
* 对于单例模式,是在关闭容器之前执行
* 对于多实例模式,ICO容器不负责销毁对象,因此销毁方法也不负责执行
*/
@Configuration
public class LifeBeanConfig { /**
* 单例模式注册Car
* bean初始化阶段调用onInit方法
* bean销毁阶段调用onDestroy方法
*/
@Bean(value = "singleCar", initMethod = "onInit", destroyMethod = "onDestroy")
@Scope(value = SCOPE_SINGLETON)
public Car singleCar() {
//调用无参构造器创建Car对象
Car car = new Car();
//设置属性
car.setMake("BMW X5");
car.setPrice(600000);
//返回Car对象
return car;
} /**
* 多例模式注册Car
* bean初始化阶段调用onInit方法
* bean销毁阶段调用onDestroy方法
*/
@Bean(value = "multiCar", initMethod = "onInit", destroyMethod = "onDestroy")
@Scope(value = SCOPE_PROTOTYPE)
public Car multiCar() {
//调用无参构造器创建Car对象
Car car = new Car();
//设置属性
car.setMake("BMW X5");
car.setPrice(600000);
//返回Car对象
return car;
}
}
测试单例模式
/**
* 测试使用单实例@Bean注解定义初始化和销毁阶段调用的方法
*/
@Test
public void test1() {
//创建springIOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeBeanConfig.class);
System.out.println("创建springIOC容器完成...");
//从容器中获取bean对象
Car car = (Car) applicationContext.getBean("singleCar");
System.out.println("获取bean对象完成...");
//关闭springIOC容器
((AnnotationConfigApplicationContext)applicationContext).registerShutdownHook();
System.out.println("关闭springIOC容器完成...");
}
测试结果
正在调用Car的无参构造方法……
正在为Car的make属性赋值……
正在为Car的price属性赋值……
car正在初始化……
创建springIOC容器完成...
获取bean对象完成...
关闭springIOC容器完成...
car正在销毁……
从测试结果看出,对于单例模式,初始化是在创建springIOC容器时,在执行完构造方法和属性赋值方法之后执行的,销毁是在执行关闭容器方法之后、容器真正关闭之前执行的
测试原型模式
/**
* 测试使用多实例@Bean注解定义初始化和销毁阶段调用的方法
*/
@Test
public void test2() {
//创建springIOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeBeanConfig.class);
System.out.println("创建springIOC容器完成...");
//从容器中获取bean对象
Car car = (Car) applicationContext.getBean("multiCar");
System.out.println("获取bean对象完成...");
//关闭springIOC容器
((AnnotationConfigApplicationContext)applicationContext).registerShutdownHook();
System.out.println("关闭springIOC容器完成...");
}
测试结果
创建springIOC容器完成...
正在调用Car的无参构造方法……
正在为Car的make属性赋值……
正在为Car的price属性赋值……
car正在初始化……
获取bean对象完成...
关闭springIOC容器完成...
从测试结果可以看出,对于原型模式,初始化是在获取bean对象时,在执行完构造方法和属性赋值方法之后执行的,没有销毁过程,即使容器关闭也并没有销毁。
2. 通过实现spring提供的接口,定义初始化阶段和销毁阶段需要执行的方法
在bean类上实现InitializingBean,其实现方法afterPropertiesSet会在初始化阶段完成了构造方法和属性赋值之后被执行,相当于上述initMethod;
同理,在bean类上实现DisposableBean接口,其实现方法destroy为在销毁阶段关闭了容器之后被执行,相当于上述destroyMethod。
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean; /**
* bean类
* 通过实现spring提供的接口,定义在初始化和销毁阶段要调用的方法
*/
public class Bus implements InitializingBean, DisposableBean { /**
* 初始化阶段,在完成属性赋值方法之后调用的方法
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("正在对bus对象进行初始化...");
} /**
* 销毁阶段,在关闭容器之后调用的方法
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("正在对bus对象进行销毁...");
} ...
}
3. 通过加JSR-250规范的注解,定义初始化阶段和销毁阶段需要执行的方法
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; /**
* bean类
* 通过加JSR-250注解,定义在初始化和销毁阶段要调用的方法
*/
public class Bus { //初始化阶段调用的方法
@PostConstruct
public void postConstruct() {
System.out.println("postConstruct...");
} //销毁阶段调用的方法
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy...");
} ...
}
那么,在同一个bean类上定义initMethod/destroyMethod方法、实现InitializingBean/Disposable接口、加PostContruct/PreDestroy注解,这三组方法的执行顺序如何?经测试,JSR-250注解先执行,spring接口第二个执行,bean注解声明的initMethod/destroyMethod最后执行。
package cn.monolog.entity; import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; /**
* bean类
* 分别通过三种方式定义初始化阶段和销毁阶段要调用的方法
*/
public class Bus implements InitializingBean, DisposableBean { //初始化阶段调用的方法,需要在配置类的@Bean注解中将该方法定义为initMethod
public void onInit() {
System.out.println("initMethod...");
} //销毁阶段调用的方法,需要在配置类的@Bean注解中将该方法定义为destroyMethod
public void onDestroy() {
System.out.println("destroyMethod...");
} /**
* 初始化阶段,在完成属性赋值方法之后调用的方法
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean...");
} /**
* 销毁阶段,在关闭容器之后调用的方法
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean...");
} //初始化阶段调用的方法
@PostConstruct
public void postConstruct() {
System.out.println("postConstruct...");
} //销毁阶段调用的方法
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy...");
} ...
}
@Test
public void test() {
//创建springIOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeBeanConfig.class);
System.out.println("创建springIOC容器完成...");
//关闭springIOC容器
((AnnotationConfigApplicationContext)applicationContext).registerShutdownHook();
System.out.println("关闭springIOC容器完成...");
}
测试结果:
正在调用bus的无参构造方法...
正在对bus的make属性进行赋值...
正在对bus的price属性进行赋值...
postConstruct...
InitializingBean...
initMethod...
创建springIOC容器完成...
关闭springIOC容器完成...
preDestroy...
DisposableBean...
destroyMethod...
三种方式创建bean对象在springIOC容器中初始化、销毁阶段要调用的自定义方法的更多相关文章
- 于Unity3D动态创建对象和创建Prefab三种方式的原型对象
于Unity3D动态创建对象和创建Prefab三种方式的原型对象 u3d在动态创建的对象,需要使用prefab 和创建时 MonoBehaviour.Instantiate( GameObject o ...
- sping练习,在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台。
相关 知识 >>> 相关 练习 >>> 实现要求: 在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台.要 ...
- Spring实例化Bean的三种方式及Bean的类型
1.使用类构造器实例化 [默认的类构造器] <bean id=“orderService" class="cn.itcast.OrderServiceBean"/ ...
- 为ScrollView增加圆角的三种方式,及自定义属性【在Linearlayout中新增ScrollView支持滚动 后续】
获取圆角的几种方案如下:方案一:通过shape来实现,给scrollView增加背景来实现方案二:通过自定义ScrollView,还要自定义属性,在dispatchDraw中不停的裁剪方案三:用And ...
- Android 三种方式实现自定义圆形页面加载中效果的进度条
转载:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=76872 一.通过动画实现 定义res/anim/loading.xml如 ...
- 阶段3 2.Spring_03.Spring的 IOC 和 DI_6 spring中bean的细节之三种创建Bean对象的方式
目前这里能调用是因为,在service的实现类里面,new了一个dao的对象 正常情况下 这里不应该是new一个对象,应该等于null或为空 设置为空侯再运行就会报错 出错的原因是这里为null 需要 ...
- 创建 Spring容器的三种方式
一.src路径下打包完在war包的classes层级下 1.Spring容器创建的三种方式 创建Bean容器之后创建对象: 其中第三种使用的是BeanFactory对象 2.spring通过配置文件用 ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService
前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...
随机推荐
- python学习第五十二天logging模块的使用
很多程序都有记录日志的需求,并且日志包含的信息即有正常的程序访问日志,还可能有错误,警告等信息输出,python的 logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...
- 通过修改host解决VS2019下载极慢的问题
原文:通过修改host解决VS2019下载极慢的问题 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...
- 自我笔记,Rides介绍
Redis是一个key-value存储系统,和Memccached类似,支持存储的value类型相对更多,很大程度上补偿memcached这类key-value存储的不足 他提供了Java,c/c++ ...
- npm学习(一)之安装、更新以及管理npm版本
安装npm 安装前须知: npm是在Node中编写的,因此需要安装Node.js才能使用npm.可以通过Node.js网站安装npm,或者安装节点版本管理器NVM. 如果只是想开始探索npm,使用No ...
- Django rest_frameword 之项目流程
后端开发软件目录规范 一.Model from django.db import models # Create your models here. # 多表的设计 # 图书 作者 出版社 作者详情表 ...
- SolrCloud集群
1 SolrCloud简介 1.1什么是SolrCloud SolrCloud(solr 云)是 Solr 提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud. ...
- AlertDialog用法。
AlertDialog 可以在当前的界面弹出一个对话框,这个对话框是置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力,因此一般 AlertDialog 都是用于提示一些非常重要的内容或者警告信息 ...
- Java数据封装成树形结构,多级
参考地址:https://blog.csdn.net/chendu500qiang/article/details/91493147 1.实体类 @data public class PublishS ...
- bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...
- 【宝藏】题解(五校联考3day1)
分析 如果打爆搜的话可以拿60分. 首先知道期望是可以累加的,即i通过j去到k的期望,等于i去到j的期望加j去到k的期望. 所以令d[i]表示i的出度,F[i]表示从i到i的父亲的期望,G[i]表示i ...