Bean 的生命周期 之 后处理Bean
这里先把Bean 的生命周期总结一下,然后引出后处理Bean
首先,Bean 的生命周期总共有11步:
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
通过测试的话,我们能很容易的验证这11个步骤,但是这11个步骤里面最重要的还是第5步和第8步
然而,第五步是在Bean初始化之前执行,我不知道这一步有什么用(请大神指点)
但是我知道,在第8步里面,可以添加一些自己的代码,就可以实现对方法的增强!也就是我们执行业务(第九步)之前就可以调用。然后对指定的方法进行增强
大家一定要注意,第五步和第八步室友前提的存在类实现 BeanPostProcessor 这里用户色标出希望大家注意!!!!!!!
也就是我们自己要定义一个后处理器,并实现其中的两个方法!如下代码:
public class MyBeanPostProcessor implements BeanPostProcessor{
/**
* bean:实例对象
* beanName:在配置文件中配置的类的标识.
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("第五步:初始化之前执行...");
return bean;
}
public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
System.out.println("第八步:初始化后执行...");
}
}
这就是一个后处理器!没初始化一个Bean,都会调用第五步和第八步,所以,通过这一点,我们就可以增强自己的代码!
在第八步里面(postProcessAfterInitialization()),我们就可以编写自己的增强。
但是,这里注意一点就是:我们定义的这个后处理器,也是需要在配置文件中添加的。Spring在初始化bean过程中如果发现bean实现了BeanPostProcessor 接口,将会将其注册为bean后处理器,它对spring容器下的所有bean起作用,任何bean在 初始化过程都会通过bean后处理器做额外增强操作。
如下是测试类的代码:
public void demo1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
customerService.add();
customerService.find();
applicationContext.close();
}
但是我们不想让所有的Bean 都被增强,这时候就可以使用动态代理来解决这个问题,可以做到只对某个方法进行增强。
代码如下:
public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
System.out.println("第八步:初始化后执行...");
// 动态代理:
if(beanName.equals("customerService")){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces() , new InvocationHandler() {
// 调用目标方法的时候,调用invoke方法.
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if("add".equals(method.getName())){
System.out.println("权限校验...");
Object result = method.invoke(bean, args);
System.out.println("权限校验后。。。");
//System.out.println(System.currentTimeMillis());
return result;
}
return method.invoke(bean, args);
}
});
return proxy;
}
return bean;
}
这里用到了动态代理,只对customerService的add方法进行增强!!!
这里还要注意一点,我们这用的是JDK的动态代理,所以被代理的类必须实现某个接口才行!!!,所以,customerService是实现类接口的类!
而测试结果就很明显了:

在调用add方法之后,会自动调用代理方法中的两个输出语句!
其实后面学习的动态代理用到的就是后处理Bean的知识.
Bean 的生命周期 之 后处理Bean的更多相关文章
- day38 09-Spring类的完整生命周期及后处理Bean
可以配置Bean的这个类的初始化和销毁的方法. 如何销毁这个bean?销毁必须得手动地关闭掉容器才行.而且销毁必须是在scope="singleton"下才有效.因为如果你scop ...
- 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的
在前面的两篇博文<一次性讲清楚spring中bean的生命周期之一:getSingleton方法>和<一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今 ...
- JAVA面试题:Spring中bean的生命周期
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...
- Spring bean的生命周期详解
bean的生命周期1.实例化bean 即new2.按照spring上下文对实例化的bean进行配置 即填充属性,也就是IOC/DI(控制反转,依赖注入)3.如果这个bean实现了BeanNameAwa ...
- spring bean的生命周期与作用域
bean的作用域 singleton:单例模式,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象. prototype:原型模式,每次通过Spri ...
- spring-第八篇之容器中的bean的生命周期
1.容器中的bean的生命周期 spring容器可以管理singleton作用域的bean的生命周期,包括bean何时被创建.何时初始化完成.何时被销毁.客户端代码不能控制该类型bean的销毁.spr ...
- SpringBean容器启动流程+Bean的生命周期【附源码】
如果对SpringIoc与Aop的源码感兴趣,可以访问参考:https://javadoop.com/,十分详细. 目录 Spring容器的启动全流程 Spring容器关闭流程 Bean 的生命周期 ...
- Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!
点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...
- Java开发学习(五)----bean的生命周期
一.什么是生命周期 首先理解下什么是生命周期? 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期. bean生命周期是什么? bean对象从创建到销毁的整体过程. bean生命周期 ...
随机推荐
- Hybrid App开发之jQuery选择器
前言: 前面学习了JQuery的简单使用,今天进一步学习一下JQuery的选择器. 什么是选择器? JQuery选择器通过标签名.属性名或者内容对DOM元素进行快速准确的选择,而不必担心浏览器的兼容性 ...
- 浅析TCP/IP 协议
TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族. TCP/IP协议模块关系 从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层.网络层.传输层.应用层 ...
- Spring+SpringMVC+MyBatis深入学习及搭建(十四)——SpringMVC和MyBatis整合
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7010363.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十三)--S ...
- PHPCMS V9 导航栏当前栏目高亮
实际上这个东西可有可无,很多站点看似导航栏当鼠标指向后都会变化等高亮处理,一般都比较醒目,但是实质点击过去后,都还是只是刚才的样式,因为这些站点的导航栏都没有对当前选中栏目做CSS的指定变化处理. 该 ...
- ASP.NET MVC Bundling and RequireJS
关于ASP.NET MVC Bundling and RequireJS的取舍问题,最近比较困惑,我希望有一种方式可以结合两者的优点.作为.NET程序员,难道你没有过这方面的困惑吗? 因为我感觉各自都 ...
- [leetcode-567-Permutation in String]
Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...
- 【LeetCode】138. Copy List with Random Pointer
题目: A linked list is given such that each node contains an additional random pointer which could poi ...
- USACO-palsquare 遇到的一个坑
/** ID: njuwz151 TASK: palsquare LANG: C++ */ #include <iostream> #include <cstdio> #inc ...
- 手机端 图片的移动缩放旋转兼容touch
//缩放var initialScale = 1;var currentScale = 1;touch.on('#target', 'pinch', function (ev) { currentSc ...
- 严重: Could not synchronize database state with session org.hibernate.exception.DataException: Could not execute JDBC batch update
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco; color: #ff2600 } p.p2 { margin: 0.0px 0 ...