[译]9-spring bean的生命周期
spring中bean的生命周期比较容易理解.bean在实例化之后有时需要调用某个初始化方法进行一些初始化的工作.同样的
,当bean在销毁之前有时需要做一些资源回收的工作.
尽管bean在实例化和销毁的时候背后会发生很多事情.但是本章我们只会介绍bean实例化和销毁过程中会回调的两个生命
周期方法.
1.初始化回调方法
当我们从spring IOC容器中拿到某个bean的实例的时,Spring IOC会按如下流程进行处理:
- 首先spring IOC容器会使用new或者工厂类来实例化bean,再次过程中可能会使用构造器参数进行依赖项的注入
- 在bean实例上调用setter方法进行依赖项的注入
- 调用bean实例的初始化方法
有两种方式指定bean的初始化方法,下面将分别介绍
1.1.继承InitializingBean接口
InitializingBean包含一个需要实现的方法-afterPropertiesSet,我们的bean可以继承InitializingBean接口并实现这个
方法.在afterPropertiesSet方法书写bean的初始化代码.下面直接看一个例子.
1.创建com.tutorialspoint.life_cycle.init_impl包,并在包中新建HelloWorld并实现InitializingBean接口,如下:
package com.tutorialspoint.life_cycle.init_impl; import org.springframework.beans.factory.InitializingBean; public class HelloWorld implements InitializingBean{ public HelloWorld(){
System.out.println("constructor invoked ... ");
} private String message; public String getMessage() {
return message;
} public void setMessage(String message) {
System.out.println("set method invoked ... ");
this.message = message;
} public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet method invoked ... ");
} }
2.在src目录下创建life_cycle_init_impl.xml文件.内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.life_cycle.init_impl.HelloWorld">
<property name="message" value="Hello World!"></property>
</bean> </beans>
3.在com.tutorialspoint.life_cycle.init_impl包中创建MainApp.java类,内容如下:
package com.tutorialspoint.life_cycle.init_impl; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MailApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("life_cycle_init_impl.xml"); }
}
4.运行程序,查看结果:
从上述运行结果也可以看出.afterPropertiesSet方法调用的时机是:所有的依赖项注入完毕之后.
1.2.使用xml配置文件中bean元素的init-method属性指定
代码几乎完全一样,直接上代码.
1.新建com.tutorialspoint.life_cycle.init_xml包,并在包中新建HelloWorld类,内容如下:
package com.tutorialspoint.life_cycle.init_xml; public class HelloWorld { public HelloWorld(){
System.out.println("constructor invoked ... ");
} private String message; public String getMessage() {
return message;
} public void setMessage(String message) {
System.out.println("set method invoked ... ");
this.message = message;
}
//初始化方法
public void init(){
System.out.println("init method invoked ... ");
} }
2.在src目录下新建配置文件life_cycle_init_xml.xml.内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 通过init-method属性指定初始化方法 -->
<bean id="helloWorld" class="com.tutorialspoint.life_cycle.init_xml.HelloWorld" init-method="init">
<property name="message" value="Hello World!"></property>
</bean> </beans>
3.在com.tutorialspoint.life_cycle.init_xml包中,新建MainApp.java类,内容如下:
package com.tutorialspoint.life_cycle.init_xml; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MailApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("life_cycle_init_xml.xml"); }
}
4.运行程序,检查结果,如下:
上面介绍完了两种指定bean的生命周期初始化方法的方式.那么我们在实际使用中应该使用哪一种方式呢?推荐第二种.
1.第一种方式跟spring的代码紧耦合;第二种跟spring代码完全解耦
2.第一种方式的初始化方法名不能修改,只能是afterPropertiesSet;第二种方式的初始化方法的名字可以任意修改.
2.销毁回调方法
当spring IOC容器销毁的时候(程序运行完毕JVM退出或者手动关闭)会调用bean的销毁回调方法,有如下两种方式:
2.1.继承DisposableBean接口
1.创建com.tutorialspoint.life_cycle.destroy_impl包,并在包中新建HelloWorld.java实现DisposableBean接口:
package com.tutorialspoint.life_cycle.destroy_impl; import org.springframework.beans.factory.DisposableBean; public class HelloWorld implements DisposableBean{ public HelloWorld(){
System.out.println("constructor invoked ... ");
} private String message; public String getMessage() {
return message;
} public void setMessage(String message) {
System.out.println("set method invoked ... ");
this.message = message;
} //把回收代码放到destroy.destroy是DisposableBean接口中的方法
@Override
public void destroy() throws Exception {
System.out.println("destroy method invoked ... ");
}
}
2.在src目录下创建life_cycle_destroy_impl.xml配置文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.life_cycle.destroy_impl.HelloWorld">
<property name="message" value="Hello World!"></property>
</bean> </beans>
3.在com.tutorialspoint.life_cycle.destroy_impl包中新建MainApp.java类,内容如下:
package com.tutorialspoint.life_cycle.destroy_impl; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) {
/**
* 使用如下这行代码进行测试,发现并没有执行destroy方法,这是因为程序运行完毕之后,JVM直接退出.
* 输入如下:
* constructor invoked ...
* set method invoked ...
*/
//ApplicationContext context = new ClassPathXmlApplicationContext("life_cycle_destroy_impl.xml"); /**
* spring提供了AbstractApplicationContext类,该类中有两个非常有用的方法:close和registerShutdownHook
* close方法提供了手动关闭spring IOC容器的实现
* registerShutdownHook方法使spring容器订阅JVM退出的事件,JVM退出时会回调spring容器的close方法.
*/
AbstractApplicationContext context = new ClassPathXmlApplicationContext("life_cycle_destroy_impl.xml");
context.close();
//context.registerShutdownHook(); }
}
4.运行程序,检查结果:
2.2.使用xml配置文件中bean元素的destroy-method属性指定
直接上代码.
1.新建com.tutorialspoint.life_cycle.destroy_xml包,并在包中新建HelloWorld.java,内容如下:
package com.tutorialspoint.life_cycle.destroy_xml; public class HelloWorld { public HelloWorld(){
System.out.println("constructor invoked ... ");
} private String message; public String getMessage() {
return message;
} public void setMessage(String message) {
System.out.println("set method invoked ... ");
this.message = message;
} public void destroy() {
System.out.println("destroy method invoked ... ");
}
}
2.在src目录下新建life_cycle_destroy_xml.xml配置文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 通过bean元素的destroy-method属性指定销毁回调方法 -->
<bean id="helloWorld" class="com.tutorialspoint.life_cycle.destroy_xml.HelloWorld" destroy-method="destroy">
<property name="message" value="Hello World!"></property>
</bean> </beans>
3.在com.tutorialspoint.life_cycle.destroy_xml包中新建MainApp.java类,内容如下:
package com.tutorialspoint.life_cycle.destroy_xml; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("life_cycle_destroy_xml.xml");
context.close();
}
}
4.运行程序,检查结果:
3.默认初始化和销毁方法
程序中可能会多类都有相同的初始化或资源回收方法。如,有一个程序,程序中大量的类都有init初始化方法,同时也有
destroy资源回收方法的话.我们可以通过指定<beans>元素的default-init-method和default-destroy-method属性
来指定spring容器中bean的默认的初始化方法和销毁方法.如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-init-method="init"
default-destroy-method="destroy"> <bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean> </beans>
[译]9-spring bean的生命周期的更多相关文章
- Spring Bean的生命周期(非常详细)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
- spring bean的生命周期
掌握好spring bean的生命周期,对spring的扩展大有帮助. spring bean的生命周期(推荐看) spring bean的生命周期
- Spring Bean的生命周期,《Spring 实战》书中的官方说法
连着两天的面试 ,都问到了 Spring 的Bean的生命周期,其中还包括 昨晚一波阿里的电话面试.这里找到了Spring 实战中的官方说法.希望各位要面试的小伙伴记住,以后有可能,或者是有时间 去看 ...
- Spring Bean的生命周期相关博客
最近得面试题一直 问 Spring 得生命周期,鉴于自己还未阅读过源码 所以只能是自己 背一波了.属实不懂硬背得作用,但是无奈被各位面试官打败了.等以后有时间了 一定要阅读几遍spring的 源码 有 ...
- Spring学习手札(四)谈谈Spring Bean的生命周期及作用域
在Spring中,那些组成应用程序的主体以及由Spring IoC容器所管理的对象,被称之为Bean.Bean与应用程序中其他对象(比如自己创建类)的区别就是,Bean是由IoC容器创建于销毁的.在S ...
- Spring Bean的生命周期详解(转)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
- Spring动态代理及Spring Bean的生命周期
数组添加值 public class DiTest { /** * 数组 */ private String [] arrays; /** * List:集合 */ private List<I ...
- Spring(三)--Spring bean的生命周期
Spring bean的生命周期 ApplicationContext Bean生命周期流程 1.需要的实体类 ackage com.xdf.bean; import org.springframew ...
- 第37讲 谈谈Spring Bean的生命周期和作用域
在企业应用软件开发中,Java 是毫无争议的主流语言,开放的 Java EE 规范和强大的开源框架功不可没,其中 Spring 毫无疑问已经成为企业软件开发的事实标准之一.今天这一讲,我将补充 Spr ...
- Spring原理系列一:Spring Bean的生命周期
一.前言 在日常开发中,spring极大地简化了我们日常的开发工作.spring为我们管理好bean, 我们拿来就用.但是我们不应该只停留在使用层面,深究spring内部的原理,才能在使用时融汇贯通. ...
随机推荐
- Poj(1703),种类并查集
题目链接:http://poj.org/problem?id=1703 已经不是第一次接触种类并查集了,直到今天才搞懂. 感谢红黑联盟,感谢杰哥!!! 每个节点只要关系确定,不管是不是同一个集合里面, ...
- Buffer实例
互联网的基础是数据的传送,一切都围绕着数据展开,比如发送啊,接收啊,这一切都离不开网络,通过之前,学会了通过http模块来搭建一个服务器,也实现了网络爬虫,nodejs中网络的部分,Net这个模块,对 ...
- windows2003服务器双线双IP双网卡设置方法
双线双ip很好,网通用户访问网通线路,电信用户访问电信线路.但很多人会选用导入静态路由表,这个办法看似完美,其实问题很多. 1.电信用户如果被解析到网通的ip上,服务器根据路由表会返回电信线路,但用户 ...
- Linux内存管理 —— 内核态和用户态的内存分配方式
1. 使用buddy系统管理ZONE我的这两篇文章buddy系统和slab分配器已经分析过buddy和slab的原理和源码,因此一些细节不再赘述.所有zone都是通过buddy系统管理的,buddy ...
- RDVTabBarController--可自由定制的iOS底部导航控件
RDVTabBarController:一个十分完善的tabBarController,可以自定义角标个数,爽的停不下来. RDVTabBarController地址:RDVTabBarControl ...
- 基于asp.net MVC 的服务器和客户端的交互(一)
架构思想 三层架构 提出了一种基于ASP.NET开发方式的三层架构的Web应用系统构造思想.其基本内容是:将面向对象的UML建模与Web应用系统开发 相结合,将整个系统分成适合ASP.NET开发方式的 ...
- 远程桌面连接失败,提示CredSSP加密Oracel修正问题解决
今天远程桌面的时候失败了,出现以下提示 于是上网找解决办法,经过测试,该方法是可行的. 首先,在控制台中输入regedit,打开注册表
- CentOS 系统 Docker 的命令大全
本文记录 CentOS 系统 Docker 的命令大全 命令 docker ps 显示运行中的容器 docker ps -a 显示所有容器 docker start 容器名称 启动容器 docker ...
- spring框架中@PostConstruct的实现原理
在spring项目经常遇到@PostConstruct注解,首先介绍一下它的用途: 被注解的方法,在对象加载完依赖注入后执行. 此注解是在Java EE5规范中加入的,在Servlet生命周期中有一定 ...
- Java高并发之线程基本操作
结合上一篇同步异步,这篇理解线程操作. 1.新建线程.不止thread和runnable,Callable和Future了解一下 package com.thread; import java.tex ...