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容器中初始化、销毁阶段要调用的自定义方法的更多相关文章

  1. 于Unity3D动态创建对象和创建Prefab三种方式的原型对象

    于Unity3D动态创建对象和创建Prefab三种方式的原型对象 u3d在动态创建的对象,需要使用prefab 和创建时 MonoBehaviour.Instantiate( GameObject o ...

  2. sping练习,在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台。

    相关 知识 >>> 相关 练习 >>> 实现要求: 在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台.要 ...

  3. Spring实例化Bean的三种方式及Bean的类型

    1.使用类构造器实例化  [默认的类构造器] <bean id=“orderService" class="cn.itcast.OrderServiceBean"/ ...

  4. 为ScrollView增加圆角的三种方式,及自定义属性【在Linearlayout中新增ScrollView支持滚动 后续】

    获取圆角的几种方案如下:方案一:通过shape来实现,给scrollView增加背景来实现方案二:通过自定义ScrollView,还要自定义属性,在dispatchDraw中不停的裁剪方案三:用And ...

  5. Android 三种方式实现自定义圆形页面加载中效果的进度条

    转载:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=76872 一.通过动画实现 定义res/anim/loading.xml如 ...

  6. 阶段3 2.Spring_03.Spring的 IOC 和 DI_6 spring中bean的细节之三种创建Bean对象的方式

    目前这里能调用是因为,在service的实现类里面,new了一个dao的对象 正常情况下 这里不应该是new一个对象,应该等于null或为空 设置为空侯再运行就会报错 出错的原因是这里为null 需要 ...

  7. 创建 Spring容器的三种方式

    一.src路径下打包完在war包的classes层级下 1.Spring容器创建的三种方式 创建Bean容器之后创建对象: 其中第三种使用的是BeanFactory对象 2.spring通过配置文件用 ...

  8. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  9. java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

随机推荐

  1. C++的同名属性(没有虚拟属性)、同名普通函数、同名静态函数(没有虚拟静态函数),是否被覆盖

    例子1:属性的覆盖#include "stdafx.h" class A {public: int i; A() { i=1; }}; class B: public A {pub ...

  2. P3158 [CQOI2011]放棋子(dp+组合数)

    P3158 [CQOI2011]放棋子 放棋子的顺序和方案数无关,所以可以从按颜色递推 设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数 $g[u][i][j]$表示第$u$ ...

  3. WPF拖拽文件(拖入拖出),监控拖拽到哪个位置,类似百度网盘拖拽

    1.往wpf中拖文件 // xaml <Grid x:Name="grid_11" DragOver="Grid_11_DragOver" Drop=&q ...

  4. es6 generator函数的异步编程

    es6 generator函数,我们都知道asycn和await是generator函数的语法糖,那么genertaor怎么样才能实现asycn和await的功能呢? 1.thunk函数    将函数 ...

  5. 前端开发HTML&css入门——CSS&选择器练习

    CSS 层叠样式表 (Cascading Style Sheets)css可以用来为网页创建样式表,通过样式表可以对网页进行装饰.所谓层叠,可以将整个网页想象成是一层一层的结构,层次高的将会覆盖层次低 ...

  6. Auth主件的(RBAC) 六表

    1.RBAC 和Auth的区别 基于RBAC一般Djagno 会用 和Auth 相对来说高级一点 2.RBAC( role Based Accsess Control)的六表之间的数据传输 2.1 D ...

  7. #include <xxx.h>和#include "xxx.h"的区别

    <>代表在系统目录下查找该头文件(系统定义头文件) ""代表在用户目录下查找该头文件(自定义头文件)

  8. Linux系统性能测试工具(八)——网络性能测试工具之netperf

    本文介绍关于Linux系统(适用于centos/ubuntu等)的网络性能测试工具-iperf.磁盘io性能测试工具包括: iperf: netperf 参考链接:https://www.jiansh ...

  9. Mysql 服务器管理程序 mysqladmin

    mysqladmin [oprions] command 选项                                      说明 create db_name               ...

  10. HTML5初识

    HTML:超文本标记语言 HTML文档树结构 标签:有一对<>组成的,标签不区分大小写,大多数都是成对出现,有开始标签和结束标签,但也有单个出现的自闭和标签 标签属性:以键值对放在标签中, ...