2017-11-06 18:59:30

  • Bean初始化和销毁方法

配置初始化和销毁的方法:
* init-method=”setup”
* destroy-method=”teardown”
执行销毁的时候,必须手动关闭工厂,而且只对scope=” singleton ”(也就是默认值)有效。

配置文件:

<?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"> <bean id="bean" class="spring3.Bean" init-method="setup" destroy-method="teardown">
<property name="s" value="hello"/>
</bean> </beans>

代码文件:

public class Bean {
private String s; public void setS(String s) {
this.s = s;
} public void setup(){
System.out.println("这是初始化方法");
} public void teardown(){
System.out.println("这是销毁方法");
}
} public class Spring3 { @Test
public void demo1(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("" +
"config2.xml"); Bean b = (Bean) ac.getBean("bean"); // 只有ClassPathXmlApplicationContext有close()方法,ApplicationContext没有
ac.close();
}
}
  • Bean的生命周期

Bean的生命周期的个步骤:
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName(让当前类了解Spring容器)
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象setApplicationContext(让当前类了解Spring容器)
5.如果存在类实现 BeanPostProcessor(前处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy

配置文件:

<?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"> <bean id="bean" class="spring3.Bean" init-method="setup" destroy-method="teardown">
<property name="s" value="hello"/>
</bean> <!--后处理bean不需要添加id,系统会自动调用-->
<bean class="spring3.MyBeanPostProcessor"/> </beans>

代码文件:

public interface B {
public void add();
} public class Bean implements B,DisposableBean,BeanNameAware,ApplicationContextAware,InitializingBean{
private String s; Bean(){
System.out.println("第一步:默认构造方法");
} public void setS(String s) {
System.out.println("第二步:属性注入");
this.s = s;
} public void add(){
System.out.println("第九步:处理业务逻辑");
System.out.println("这是添加方法");
} public void setup(){
System.out.println("第七步:这是初始化方法");
} public void teardown(){
System.out.println("这是销毁方法");
} @Override
public void setBeanName(String s) {
System.out.println("第三步:注入配置的id号"+s);
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:注入ApplicationContext"+applicationContext);
} @Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后执行");
} @Override
public void destroy() throws Exception {
System.out.println("第十步:Spring调用销毁方法");
}
}

自定义的 BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* bean:实例对象
* beanName:在配置文件中配置的类的标识.
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("第五步:初始化之前执行...");
return bean;
} public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
System.out.println("第八步:初始化后执行...");
return bean;
}
}

结果:

    public void demo1(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("" +
"config2.xml"); Bean b = (Bean) ac.getBean("bean");
b.add();
// 只有ClassPathXmlApplicationContext有close()方法,ApplicationContext没有
ac.close();
} 输出:
第一步:默认构造方法
第二步:属性注入
第三步:注入配置的id号bean
第四步:注入ApplicationContextorg.springframework.context.support.ClassPathXmlApplicationContext@6591f517: startup date [Mon Nov 06 19:50:53 CST 2017]; root of context hierarchy
第五步:初始化之前执行...
第六步:属性设置后执行
第七步:这是初始化方法
第八步:初始化后执行...
第九步:处理业务逻辑
这是添加方法
第十步:Spring调用销毁方法
这是销毁方法

当然了在后处理Bean的时候是可以进行动态代理进行增强的。

但是要特别注意,这个时候在定义对象的时候,必须是使用接口来作为类型名,而不能是实现类,因为这次返回的是代理类,代理类和实现类是平级关系,是无法相互转换的。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* bean:实例对象
* beanName:在配置文件中配置的类的标识.
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("第五步:初始化之前执行...");
return bean;
} public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
System.out.println("第八步:初始化后执行...");
// 动态代理进行增强
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验:");
Object res = method.invoke(bean, args);
return res;
}
});
return proxy;
}
} public class Spring3 { @Test
public void demo1(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("" +
"config2.xml"); B b = (B) ac.getBean("bean");
b.add();
// 只有ClassPathXmlApplicationContext有close()方法,ApplicationContext没有
ac.close();
}
} 结果:
第一步:默认构造方法
第二步:属性注入
第三步:注入配置的id号bean
第四步:注入ApplicationContextorg.springframework.context.support.ClassPathXmlApplicationContext@6591f517: startup date [Mon Nov 06 20:18:39 CST 2017]; root of context hierarchy
第五步:初始化之前执行...
第六步:属性设置后执行
第七步:这是初始化方法
第八步:初始化后执行...
权限校验:
第九步:处理业务逻辑
这是添加方法
第十步:Spring调用销毁方法
这是销毁方法

最新文章

  1. BZOJ 1006 【HNOI2008】 神奇的国度
  2. Ros集成开发环境配置
  3. 跟我一起学WCF(8)——WCF中Session、实例管理详解
  4. RAC 环境下的重要参数
  5. leetcode刷题总结一
  6. mysql绿色版安装问题解决(ERROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;localhost&#39; (10061))
  7. 欧拉工程第65题:Convergents of e
  8. pyqt listwidget下面创建多张图片
  9. Windows 下统计行数的命令
  10. ubuntu内核的编译安装
  11. js 数组随机洗牌
  12. 从前端界面开发谈微信小程序体验
  13. 20155334 2016-2017-2 《Java程序设计》第九周学习总结
  14. win7+php5.3.10下安装memcache (转)
  15. Linux修复系统命令
  16. node进阶之用流实现上传文件
  17. JPA联合主键
  18. python实现文件夹的排序
  19. [转] 关于Struts-JSON配置(详解带实例struts2的json数据支持)
  20. 017:磁盘I/0介绍和测试

热门文章

  1. ST-LINK使用注意
  2. 170713、springboot编程之多数据源切换
  3. 转载:隐式Intent
  4. Oracle之rman命令的使用全备输出信息的详解(51CTO风哥rman课程)
  5. Unity-DLL反编译学习
  6. H5保养
  7. 使用JavaScript修改浏览器URL地址栏的实现代码
  8. python+Nginx+uWSGI使用说明
  9. HTML5中的本地、WebSql、离线应用存储
  10. linux磁盘空间使用问题