文档章节

spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)

T-Brain
 T-Brain
发布于 2015/10/20 01:26
字数 1318
阅读 119
收藏 0

* 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;
     }
}



© 著作权归作者所有

共有 人打赏支持
T-Brain
粉丝 1
博文 44
码字总数 46138
作品 0
海淀
程序员
私信 提问
9.01-Spring IOC 容器中Bean的生命周期

Spring IOC 容器可以管理Bean的生命周期,Spring 允许在Bean的生命周期的特定点执行定制的任务。 Spring IOC 容器中 Bean 的生命周期如下: ① . 通过构造器或工厂方法创建 Bean 实例 : 调用...

静以修身2025
06/27
0
0
Spring中管理Bean依赖注入之后和Bean销毁之前的行为

对于Singleton作用域的Bean,Spring容器将会跟踪它们的生命周期,容器知道何时实例化结束、何时销毁。Spring可以管理Bean在实例化结束之后和Bean销毁之前的行为。 Bean依赖关系注入之后的行为...

摆渡者
2014/03/06
0
0
Spring核心——Bean的定义与控制

在前面两篇介绍Sring核心与设计模式的文章中,分别介绍了Ioc容器和Bean的依赖关系。如果阅读过前2文就会知道,Spring的整个运转机制就是围绕着IoC容器以及Bean展开的。IoC就是一个篮子,所有...

随风溜达的向日葵
06/28
0
0
Spring Bean配置默认为单实例 pring Bean生命

Bean默认的是单例的. 如果不想单例需要如下配置: <bean id="user" class="..." singleton="false"/> singleton就是配置这个bean是否是单例的,如果不写,就是默认值true。 注解: spring B...

西行侠客
2014/08/30
0
0
Spring之Bean的作用域与生命周期

Version:1.0 StartHTML:000000209 EndHTML:000019387 StartFragment:000001892 EndFragment:000019301 StartSelection:000001892 EndSelection:000019291 SourceURL:https://www.cnblogs.com......

小七奇奇
08/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No credential found 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清...

hengyunabc
26分钟前
0
0
home hosts

home hosts lwk@qwfys:~$ cat /etc/hosts127.0.0.1 localhost127.0.1.1 qwfys192.168.56.101vm600.qwfys.com39.108.212.91alpha1.ppy.com39.108.117.122alpha2.p......

qwfys
33分钟前
0
0
大数据教程(6.1)hadoop生态圈介绍及就业前景

1. HADOOP背景介绍 1.1、什么是HADOOP 1.HADOOP是apache旗下的一套开源软件平台 2.HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理 3.HADOOP的核心组...

em_aaron
今天
2
0
hadoop垃圾回收站

在生产生,hdfs回收站必须是开启的,一般设置为7天。 fs.trash.interval 为垃圾回收站保留时间,如果为0则禁用回收站功能。 fs.trash.checkpoint.interval 回收站检查点时间,一般设置为小于...

hnairdb
昨天
3
0
腾讯与Github的魔幻会面背后的故事…

10月22日,腾讯开源管理办公室有幸邀请到Github新晋CEO Nat Friedman,前来鹅厂参观交流。目前腾讯已经有近70个项目在Github上开源,共获得17w stars,世界排名11位。Github是腾讯开源的主阵...

腾讯开源
昨天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部