文档章节

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

T-Brain
 T-Brain
发布于 2015/10/20 01:26
字数 1318
阅读 138
收藏 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
Bean在Spring容器中的生命周期

配置在Spring中的Bean在Spring容器中从加载到销毁会经历那些过程呢?如果实现一些特定的Spring接口,这些特定接口的方法会在什么时候被调用呢?本文简单介绍一下这些过程. Bean在Spring容器中的...

晨曦之光
2012/04/25
573
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

没有更多内容

加载失败,请刷新页面

加载更多

RestClientUtil和ConfigRestClientUtil区别说明

RestClientUtil directly executes the DSL defined in the code. ConfigRestClientUtil gets the DSL defined in the configuration file by the DSL name and executes it. RestClientUtil......

bboss
5分钟前
0
0

中国龙-扬科
昨天
0
0
Linux系统设置全局的默认网络代理

更改全局配置文件/etc/profile all_proxy="all_proxy=socks://rahowviahva.ml:80/"ftp_proxy="ftp_proxy=http://rahowviahva.ml:80/"http_proxy="http_proxy=http://rahowviahva.ml:80/"......

临江仙卜算子
昨天
3
0
java框架学习日志-6(bean作用域和自动装配)

本章补充bean的作用域和自动装配 bean作用域 之前提到可以用scope来设置单例模式 <bean id="type" class="cn.dota2.tpye.Type" scope="singleton"></bean> 除此之外还有几种用法 singleton:......

白话
昨天
7
0
在PC上测试移动端网站和模拟手机浏览器的5大方法

总结很全面,保存下来以备不时之需。原文地址:https://www.cnblogs.com/coolfeng/p/4708942.html

kitty1116
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部