spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)
* Bean的生命周期
* init-method:初始化的时候执行的方法:
*destroy-method:销毁的时候执行的方法:
* Bean生成必须是单例的.在工厂关闭的时候销毁.
但是关闭必须手动执行手动销毁的方法.也就是applicationContext.closed()
Bean的完整的生命周期有十一个步骤:
1.instantiate bean对象实例化(初始化)
2.populate properties 封装属性(属性的注入)
3.如果Bean实现BeanNameAware 执行 setBeanName(配置Spring中的id或者name)
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization(执行初始化之前执行的方法)(AOP底层)
6.如果Bean实现InitializingBean 执行 afterPropertiesSet (属性注入完成)
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization(执行初始化之后执行的方法)(AOP底层)
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
* 第三步和第四步:让JavaBean了解Spring的容器.
***** 第五步和第八步非常重要:
BeanPostPorcessor:在Bena的实例化的过程中对Bean进行增强. (需要自己配置,配置不需要配ID,也叫后处理Bean,Spring 底层会自动调)
* Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
* 增强一个Bean中某个方法需要几种方式:
* 继承:
* 能够控制这类的构造!!!,这个类你可以自己去new它或者你自己能提供这个类
* 装饰者模式:
* 被增强类和增强类实现相同的接口.
* 在增强的类中获得到被增强类的引用.
***** 缺点:接口中方法太多.其他都需要原封调用.
* 动态代理:(灵活)
* JDK动态代码:类实现接口.
* 对实现接口的类产生代理.
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package com.mickeymouse.spring.demo4;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Bean的完整的生命周期的十一个步骤:
*/
public class ProductDaoImpl implements ProductDao,BeanNameAware ,ApplicationContextAware,InitializingBean,DisposableBean {
private String name;
public ProductDaoImpl() {
super ();
System.out.println( "第一步:实例化Bean" );
}
public void setName(String name) {
System.out.println( "第二步:属性注入:" +name);
this .name = name;
}
@Override
public void setBeanName(String beanName) {
System.out.println( "第三步:获得Bean的名称" +beanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println( "第四步:让Bean了解Spring的工厂..." );
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println( "第六步:属性设置完成..." );
}
public void setup(){
System.out.println( "第七步:执行手动配置的初始化方法..." );
}
public void save(){
System.out.println( "第九步:执行业务save方法..." );
}
public void update(){
System.out.println( "第九步:执行业务update方法..." );
}
@Override
public void destroy() throws Exception {
System.out.println( "第十步:执行Spring中提供的对象销毁的方法..." );
}
public void teardown(){
System.out.println( "第十一步:执行手动配置的销毁的方法" );
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package com.mickeymouse.spring.demo4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println( "第五步:执行初始化前执行的方法..." );
return bean;
}
@Override
public Object postProcessAfterInitialization( final Object bean, String beanName)
throws BeansException {
System.out.println( "第八步:执行初始化后执行的方法..." );
// 使用动态代理:
if (beanName.endsWith( "Dao" )){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ( "save" .equals(method.getName())){
System.out.println( "===============权限校验" );
return method.invoke(bean, args);
}
return method.invoke(bean, args);
}
});
return proxy;
}
return bean;
}
}
|
1
2
3
4
5
|
package com.mickeymouse.spring.demo4;
public interface ProductDao {
public void save();
public void update();
}
|
XML配置
1
2
3
4
5
|
< bean id = "productDao" class = "com.itheima.spring.demo4.ProductDaoImpl" init-method = "setup" destroy-method = "teardown" >
< property name = "name" value = "空调" />
</ bean >
< bean class = "com.itheima.spring.demo4.MyBeanPostProcessor" />
|
TestDemo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.mickeymouse.spring.demo4;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Bean的完整生命周期的测试
* @author mickeymouse
*
*/
public class SpringDemo4 {
@Test
public void demo1(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml" );
ProductDao productDao = (ProductDao) applicationContext
.getBean( "productDao" );
productDao.save();
productDao.update();
applicationContext.close();
}
}
|
关于实现 BeanPostProcessor(处理Bean) ,执行postProcessXXXXInitialization(执行初始化之XXXX(前或后)执行的方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package com.mickeymouse.context;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 目的:增强我们一个对象的某个方法,让执行这个方法的时候有个权限校验
* eg:增强XXXDao这个类中的save方法
*/
public Object postProcessAfterInitialization( final Object bean, String beanname)
throws BeansException {
//判断假如我们的对象名是以Dao结尾的,那么我们就进行增增强处理
if (beanname.endsWith( "Dao" )) {
//生成代理对象
Object proxy = Proxy.newProxyInstance(MyBeanPostProcessor. class .getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
//代理对象里的方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//如果是代理执行的是save方法
if ( "save" .equals(method.getName())) {
System.out.println( "我执行了权限校验" );
return method.invoke(bean, args);
}
return method.invoke(bean, args);
}
});
return proxy;
}
//如果不是以Dao结尾额,我们不用管,原封不动的返回
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanname)
throws BeansException {
// TODO Auto-generated method stub
return bean;
}
}
|
转载于:https://my.oschina.net/mickeymouse/blog/519124
spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)相关推荐
- Spring Bean生命周期过程
Spring Bean生命周期过程 Spring Bean生命周期指的是Bean加载Spring容器的过程,单例的Bean与多例的Bean加载过程是不一样的.这里指的是单例Bean的加载过程. 图:S ...
- Spring框架:三种Spring Bean生命周期技术
当使用术语"生命周期"时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关. 在某些情况下,Bean生命周期的管理不是一件容易 ...
- Spring Bean 生命周期之“我从哪里来”?懂得这个很重要
Spring bean 的生命周期很容易理解.实例化 bean 时,可能需要执行一些初始化以使其进入可用 (Ready for Use)状态.类似地,当不再需要 bean 并将其从容器中移除时,可能需 ...
- spring bean生命周期管理--转
Life Cycle Management of a Spring Bean 原文地址:http://javabeat.net/life-cycle-management-of-a-spring-be ...
- Spring5源码 - 07 Spring Bean 生命周期流程 源码解读02
文章目录 Pre 通俗流程 finishBeanFactoryInitialization Pre Spring5源码 - 06 Spring Bean 生命周期流程 概述 01 接上文 通俗流程 下 ...
- Spring Bean生命周期: Bean的实例化
[Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...
- Spring Bean生命周期:Bean的初始化阶段
[Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...
- 浅谈spring的生命周期
文章目录 前言 生命周期 详细描述 处理名称,检查缓存 处理父子容器 处理 dependsOn 选择 scope 策略 创建 bean - 创建 bean 实例 创建 bean - 依赖注入 创建 b ...
- 面试-Spring的生命周期
Spring Bean的生命周期是Spring面试热点问题.这个问题即考察对Spring的微观了解,又考察对Spring的宏观认识,想要答好并不容易!本文希望能够从源码角度入手,帮助面试者彻底搞定Sp ...
- 【转】【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途...
原文网址:http://blog.csdn.net/weasleyqi/article/details/8090373 iOS视图控制对象生命周期-init.viewDidLoad.viewWillA ...
最新文章
- [leetcode] Bulb Switcher
- My97DatePicker日历插件
- scala函数的定义语法说明
- hdu 3706 Second My Problem First 单调队列
- Python简单试题3
- Spring Security和多个过滤器链
- 儿童编程python入门_儿童编程python入门
- 当面试官问我————为什么String是final的?
- Phonegap在ios7上系统状态栏的问题解决
- java怎么快速创建监听类_如何创建监听器
- 关于shell读取文件打印时展开通配符
- CSS:设置文字不可选
- 2015-2016书籍计划
- MPI集群安装、MPI安装
- 数据库 SQL 查询当前时间
- IDEA 安装插件后,重启插件消失问题
- 第二章---《实时语音处理实践指南》发音机理与器件学习笔记
- 谷歌浏览器被hao123绑定首页了
- 抢票显示服务器失败是什么原因,抢票网站的手机核验失败原因
- CAD删不掉的顽固图层及简单优化