spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)
博客专区 > T-Brain 的博客 > 博客详情
spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)
T-Brain 发表于2年前
spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)
  • 发表于 2年前
  • 阅读 18
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

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



共有 人打赏支持
粉丝 2
博文 44
码字总数 46138
×
T-Brain
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: