这里先把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的更多相关文章

  1. day38 09-Spring类的完整生命周期及后处理Bean

    可以配置Bean的这个类的初始化和销毁的方法. 如何销毁这个bean?销毁必须得手动地关闭掉容器才行.而且销毁必须是在scope="singleton"下才有效.因为如果你scop ...

  2. 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的

    在前面的两篇博文<一次性讲清楚spring中bean的生命周期之一:getSingleton方法>和<一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今 ...

  3. JAVA面试题:Spring中bean的生命周期

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...

  4. Spring bean的生命周期详解

    bean的生命周期1.实例化bean 即new2.按照spring上下文对实例化的bean进行配置 即填充属性,也就是IOC/DI(控制反转,依赖注入)3.如果这个bean实现了BeanNameAwa ...

  5. spring bean的生命周期与作用域

    bean的作用域 singleton:单例模式,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象. prototype:原型模式,每次通过Spri ...

  6. spring-第八篇之容器中的bean的生命周期

    1.容器中的bean的生命周期 spring容器可以管理singleton作用域的bean的生命周期,包括bean何时被创建.何时初始化完成.何时被销毁.客户端代码不能控制该类型bean的销毁.spr ...

  7. SpringBean容器启动流程+Bean的生命周期【附源码】

    如果对SpringIoc与Aop的源码感兴趣,可以访问参考:https://javadoop.com/,十分详细. 目录 Spring容器的启动全流程 Spring容器关闭流程 Bean 的生命周期 ...

  8. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  9. Java开发学习(五)----bean的生命周期

    一.什么是生命周期 首先理解下什么是生命周期? 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期. bean生命周期是什么? bean对象从创建到销毁的整体过程. bean生命周期 ...

随机推荐

  1. Android 创建虚拟机时“提示no system images installed for this target”

    经上网查证,发现原因在于CPU/ABI选项无法选择,并显示“No system images installed for this target”,也就是没有适合的系统镜像,通过与安装好了的ADT-b ...

  2. ionic 使用了 crosswalkwebview 所产生的bug 及 解决方案

    一.问题产生: 在ionic app 优化方案中,我在前之前的博文中提到使用 --crosswalkwebview: 使用了crosswalkwebview后,app的显示及兼容效果确实很不错,虽然a ...

  3. ionic 的缓存 和局部刷新

    最近两天在做项目时,发现ionic的缓存功能非常方便好用,提高了再低端手机特别是android比较低版本上的流畅性!可是,后来发现,整体的缓存整个页面并不是一个一劳永逸的办法,结合局部刷新功能,感觉就 ...

  4. jsp图片上传

    1.要实现图片上传,首先需要一个组件,这里我用的是smartupload.jar可以到这里下载http://download.csdn.net/detail/mengdecike/8279247 2. ...

  5. 如何在BCGControlBar界面库的CBCGPFormView子视图里面添加工具栏

    最近有一个项目需求,需要在子视图里面添加一个新工具栏用来处理当前视图对应模块的操作.之前在对话框模式下做过添加工具栏的实现,在CBCGPFormView中添加工具栏还是头一次.在这里记录一下,给自己留 ...

  6. react实现双向绑定

    双向绑定功能是在项目中比较常见的一个需求,传统的js实现方式是添加监听函数的方式,Vue框架实现很简单,因为它本身就是基于双向绑定实现的,接下来我将讲解一下如何使用react实现双向绑定的功能是 首先 ...

  7. vue项目构建与实战

    关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 由于vue相对来说比较平缓的学习过程和新颖的技术思路,使其受到了广大前后端开发者的青睐,同时其通俗易 ...

  8. 程序员必须知道的六大ES6新特性

    二 .字符串扩展 1.传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中.ES6又提供了三种新方法. includes():返回布尔值,表示是否找到了参 ...

  9. c#重起 普通路由器

    using DotNet.Utilities;using System;using System.Collections.Generic;using System.Linq;using System. ...

  10. Kinect用体感来实现UI控件的点击

    用体感来实现UI控件的点击,如点击按钮. 做法:用一个图片表示左手手掌,图片位置追踪左手手掌移动,当手掌位于UI控件的矩形内时,握拳表示点击该控件. using UnityEngine; using ...