文章目录
Bean 的生命周期
理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。
Bean的生命周期可以表达为:
Bean的定义——>Bean的初始化——>Bean的使用——>Bean的销毁
Bean初始化回调
InitializingBean
实现org.springframework.beans.factory.InitializingBean 接口的afterPropertiesSet方法:
- UserServiceImpl
import org.springframework.beans.factory.InitializingBean;
public class UserServiceImpl implements UserService,InitializingBean {
@Override
public void addUser() {
System.out.println("ico add user");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
- 配置
<?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.xsd">
<!-- 配置service
<bean> 配置需要创建的对象
id :用于之后从spring容器获得实例时使用的
class :需要创建实例的全限定类名
-->
<bean id="userServiceId" class="com.cc.study.ioc.UserServiceImpl"></bean>
</beans>
- 测试
@Test
public void demo(){
//从spring容器获得
//1 获得容器
String xmlPath = "beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
//2获得内容 --不需要自己new,都是从spring容器获得
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
init-method 属性
在基于 XML 的配置元数据的情况下,你可以使用 init-method 属性来指定带有 void 无参数方法的名称。例如:
- 配置
<?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.xsd">
<!--
init-method 用于配置初始化方法,准备数据等
-->
<bean id="userServiceId" class="com.cc.study.ioc.UserServiceImpl"
init-method="myInit"></bean>
</beans>
- UserServiceImpl
import org.springframework.beans.factory.InitializingBean;
public class UserServiceImpl implements UserService,InitializingBean {
@Override
public void addUser() {
System.out.println("ico add user");
}
public void myInit(){
System.out.println("初始化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
- 测试
@Test
public void demo01(){
String xmlPath = "lifecycle.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
销毁回调
DisposableBean
实现org.springframework.beans.factory.DisposableBean 接口的destroy的方法:
- UserServiceImpl
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class UserServiceImpl implements UserService,InitializingBean,DisposableBean {
@Override
public void addUser() {
System.out.println("ico add user");
}
public void myInit(){
System.out.println("初始化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
}
- 测试
@Test
public void demo01() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String xmlPath = "lifecycle.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
// applicationContext.close();
applicationContext.getClass().getMethod("close").invoke(applicationContext);
}
或者使用如下方式进行销毁容器
@Test
public void demo01() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String xmlPath = "lifecycle.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
applicationContext.close();
}
还可以使用registerShutdownHook方法进行销毁容器
@Test
public void demo01() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String xmlPath = "lifecycle.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
applicationContext.registerShutdownHook();
}
destroy-method 属性
在基于 XML 的配置元数据的情况下,你可以使用 destroy-method 属性来指定带有 void 无参数方法的名称。例如:
- 配置
<?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.xsd">
<!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="com.cc.study.ioc.UserServiceImpl"
init-method="myInit" destroy-method="myDestroy" ></bean>
</beans>
- UserServiceImpl
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class UserServiceImpl implements UserService,InitializingBean,DisposableBean {
@Override
public void addUser() {
System.out.println("ico add user");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
}
- 测试
建议不要使用 InitializingBean 或者 DisposableBean 的回调方法,因为 XML 配置在命名方法上提供了极大的灵活性。
默认的初始化和销毁方法 default-init-method 和 default-destroy-method 属性
如果有太多具有相同名称的初始化或者销毁方法的 Bean,那么你不需要在每一个 bean 上声明初始化方法和销毁方法。框架使用 元素中的 default-init-method 和 default-destroy-method 属性提供了灵活地配置这种情况,如下所示:
- 配置
<?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.xsd"
default-init-method="myInit" default-destroy-method="myDestroy">
<bean id="userServiceId" class="com.cc.study.ioc.UserServiceImpl"></bean>
</beans>
- UserServiceImpl
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class UserServiceImpl implements UserService,InitializingBean,DisposableBean {
@Override
public void addUser() {
System.out.println("ico add user");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
//建议不要使用 InitializingBean 或者 DisposableBean 的回调方法,因为 XML 配置在命名方法上提供了极大的灵活性。
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
}
- 测试
@Test
public void demo03(){
String xmlPath = "default-lifecycle.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
applicationContext.registerShutdownHook();
}