* 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.(以及初始前后代理测试)相关推荐

  1. Spring Bean生命周期过程

    Spring Bean生命周期过程 Spring Bean生命周期指的是Bean加载Spring容器的过程,单例的Bean与多例的Bean加载过程是不一样的.这里指的是单例Bean的加载过程. 图:S ...

  2. Spring框架:三种Spring Bean生命周期技术

    当使用术语"生命周期"时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关. 在某些情况下,Bean生命周期的管理不是一件容易 ...

  3. Spring Bean 生命周期之“我从哪里来”?懂得这个很重要

    Spring bean 的生命周期很容易理解.实例化 bean 时,可能需要执行一些初始化以使其进入可用 (Ready for Use)状态.类似地,当不再需要 bean 并将其从容器中移除时,可能需 ...

  4. spring bean生命周期管理--转

    Life Cycle Management of a Spring Bean 原文地址:http://javabeat.net/life-cycle-management-of-a-spring-be ...

  5. Spring5源码 - 07 Spring Bean 生命周期流程 源码解读02

    文章目录 Pre 通俗流程 finishBeanFactoryInitialization Pre Spring5源码 - 06 Spring Bean 生命周期流程 概述 01 接上文 通俗流程 下 ...

  6. Spring Bean生命周期: Bean的实例化

    [Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...

  7. Spring Bean生命周期:Bean的初始化阶段

    [Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...

  8. 浅谈spring的生命周期

    文章目录 前言 生命周期 详细描述 处理名称,检查缓存 处理父子容器 处理 dependsOn 选择 scope 策略 创建 bean - 创建 bean 实例 创建 bean - 依赖注入 创建 b ...

  9. 面试-Spring的生命周期

    Spring Bean的生命周期是Spring面试热点问题.这个问题即考察对Spring的微观了解,又考察对Spring的宏观认识,想要答好并不容易!本文希望能够从源码角度入手,帮助面试者彻底搞定Sp ...

  10. 【转】【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途...

    原文网址:http://blog.csdn.net/weasleyqi/article/details/8090373 iOS视图控制对象生命周期-init.viewDidLoad.viewWillA ...

最新文章

  1. [leetcode] Bulb Switcher
  2. My97DatePicker日历插件
  3. scala函数的定义语法说明
  4. hdu 3706 Second My Problem First 单调队列
  5. Python简单试题3
  6. Spring Security和多个过滤器链
  7. 儿童编程python入门_儿童编程python入门
  8. 当面试官问我————为什么String是final的?
  9. Phonegap在ios7上系统状态栏的问题解决
  10. java怎么快速创建监听类_如何创建监听器
  11. 关于shell读取文件打印时展开通配符
  12. CSS:设置文字不可选
  13. 2015-2016书籍计划
  14. MPI集群安装、MPI安装
  15. 数据库 SQL 查询当前时间
  16. IDEA 安装插件后,重启插件消失问题
  17. 第二章---《实时语音处理实践指南》发音机理与器件学习笔记
  18. 谷歌浏览器被hao123绑定首页了
  19. 抢票显示服务器失败是什么原因,抢票网站的手机核验失败原因
  20. CAD删不掉的顽固图层及简单优化

热门文章

  1. Python pandas 操作 csv 修改 2021/8/29
  2. slow down用法
  3. 数据化管理洞悉零售及电子商务运营——数据化管理介绍
  4. 在deepin环境下安装qt开发环境和dtk开发环境
  5. 自动化工具之tosca
  6. DAV 入门之 MATLAB (3):帮助
  7. 五一重刷的三部影视剧
  8. Android studio 软件介绍及运行到手机上
  9. css3宽度变大动画_动画演示流量计的工作原理,真涨见识
  10. 单片机——复位操作详述