4.BeanPostProcessor 后处理Bean
Bean种类
普通bean:之前操作的都是普通bean。<bean id="" class="A"> ,spring直接创建A实例,并返回
FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。
bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。
<bean id="" class="FB"> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值
FB fb = new FB();
return fb.getObject();
l BeanFactory 和 FactoryBean 对比?
BeanFactory:工厂,用于生成任意bean。
FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产代理。<bean id="" class="....ProxyFactoryBean"> 获得代理对象实例。AOP使用
作用域

取值:
singleton 单例,默认值。
prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
配置信息
<bean id="" class="" scope="">

<bean id="userServiceId" class="com.itheima.d_scope.UserServiceImpl" scope="prototype" ></bean>
生命周期
初始化和销毁
目标方法执行前后执行后,将进行初始化或销毁。
<bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称">
1 spring配置
<!-- init-method 用于配置初始化方法,准备数据等 destroy-method 用于配置销毁方法,清理资源等 --> <bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl" init-method="myInit" destroy-method="myDestroy" ></bean>
2 测试
@Test
public void demo02() throws Exception{
//spring 工厂
String xmlPath = "com/itheima/e_lifecycle/beans.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();
}
BeanPostProcessor 后处理Bean
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置<bean class="">

l Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
l spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
模拟
A a =new A();
a = B.before(a) --> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
a.init();
a = B.after(a);
a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)
a.destroy()
1.编写实现类
MyBeanPostProcessor.java
package com.jd.lifecycle; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author weihu
* @date 2018/8/12/012 23:15
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("前方法:"+o);
return o;
} @Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("后方法:"+o);
//o目标对象
//生成jdk代理
return Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(),
o.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("---开启事物-----"); //执行目标方法
Object obj = method.invoke(o, args);
System.out.println("-----提交事物-------");
return obj;
}
});
}
}
UserService.java
package com.jd.lifecycle;
public interface UserService {
public void addUser();
}
UserServiceImpl.java
package com.jd.lifecycle;
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("lifecycle add user");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="com.jd.lifecycle.UserServiceImpl" init-method="myInit"
destroy-method="myDestroy"></bean> <!--将后处理的实现类注册给spring-->
<bean class="com.jd.lifecycle.MyBeanPostProcessor"></bean> </beans>
TestCycle.java
package com.jd.lifecycle; import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author weihu
* @date 2018/8/12/012 23:24
*/
public class TestCycle { @Test
public void testProx(){
String xmlPath="com/jd/lifecycle/beans.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser(); //要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();
}
}
4.BeanPostProcessor 后处理Bean的更多相关文章
- 生命周期(初始化、销毁方法、BeanPostProcessor后处理Bean)
1.初始化和销毁 在目标方法执行前后进行初始化或销毁 (1)在Service方法的实现类里面创建初始化方法和销毁方法: public class StudentServiceImpl implemen ...
- Bean 的生命周期 之 后处理Bean
这里先把Bean 的生命周期总结一下,然后引出后处理Bean 首先,Bean 的生命周期总共有11步: 1.instantiate bean对象实例化 2.populate properties 封装 ...
- day38 09-Spring类的完整生命周期及后处理Bean
可以配置Bean的这个类的初始化和销毁的方法. 如何销毁这个bean?销毁必须得手动地关闭掉容器才行.而且销毁必须是在scope="singleton"下才有效.因为如果你scop ...
- 04Spring_bean 后处理器(后处理Bean),BeanPostProcessor ,bean创建时序,动态代理
这篇文章很重要,讲解的是动态代理,以及bean创建前后的所发生的事情.介绍一个接口:在Spring构造Bean对象过程中,有一个环节对Bean对象进行 后处理操作 (钩子函数) ----- Sprin ...
- IoC容器装配Bean(xml配置方式)(Bean的生命周期)
1.Spring管理Bean,实例化Bean对象 三种方式 第一种:使用类构造器实例化(默认无参数) package cn.itcast.spring.initbean; /** * 使用构造方法 实 ...
- spring Bean的完整生命周期
spring 容器中的bean的完整生命周期一共分为十一步完成. 1.bean对象的实例化 2.封装属性,也就是设置properties中的属性值 3.如果bean实现了BeanNameAware,则 ...
- Spring的Bean生命周期理解
首先,在经历过很多次的面试之后,一直不能很好的叙述关于springbean的生命周期这个概念.今日对于springBean的生命周期进行一个总结. 一.springBean的生命周期: 如下图所示: ...
- 装配bean,基于xml
一.bean的实例化方式 1.默认构造 <bean id="" class=""></bean> 必须提供默认构造方法 2.静态工厂 用 ...
- Spring 容器中 Bean 的生命周期
Spring 容器中 Bean 的生命周期 1. init-method 和 destory-method 方法 Spring 初始化 bean 或销毁 bean 时,有时需要作一些处理工作,因此 s ...
随机推荐
- leetcode每日刷题计划-简单篇day3
收到swe提前批面试hhh算是ep挂了的后续 努力刷题呀争取今年冲进去! Num 21 合并两个有序链表 Merge Two Sorted Lists 注意新开的链表用来输出结果的是ListNode ...
- leetcode979
搞不定这种递归计算,可能我的头脑是“线性”的,这种一层一层的,想起来太费劲了,想的头发都没了.以后希望能有AI来写这种程序吧,AI不怕掉头发! class Solution(object): def ...
- threading.local()源码分析
前段时间写了个多线程的程序,了解到Python中有个与众不同的thread.local()方法,可以创建一个全局对象,各个线程可以用这个全局对象保存各自的局部变量,而在使用时不受其他线程的影响.于是抽 ...
- 高性能迷你React框架anujs1.0.8发布
本版本由于得到业务线同学的大力支持,掀出许多问题,因此改进地方良多,为anujs在完美替换React的道路上前进了不少.现在anujs经测试可以运行于IE7中.至少怎么做可以参看官网,https:// ...
- 关于吴恩达机器学习支持向量机的问题,讲到对偶前有一个最小化f(w)使用拉格朗日求解时转化成一个最大的相等式的理解和一些困惑
(纯属个人理解) 参考: https://www.zhihu.com/question/267482928 https://www.cnblogs.com/90zeng/p/Lagrange_dual ...
- P1147连续自然数和-(尺取法)
https://www.luogu.org/problemnew/show/P1147 题意:输入一个n,求连续几个数加起来等于n,输出这几个连续的数的第一个和最后一个.10<=n<=20 ...
- 一个JavaBean和DTO转换的优秀案例
所有的JavaBean和DTO的互相转换接口,JavaBean转化成DTO或者DTO转换JavaBean: public abstract class Converter<A, B> { ...
- netstat 常用参数总结
netstat 是一个机器网络查看工具 . 网络连接有哪些参数?
- 用命令生成Webservice 对应的代理类
wsdl /language:C# /namespace:Camstar.WebPortal.WebPortlets.Shopfloor.SAP.GreatWall /out:gwSAPService ...
- 定义一个包含标签inclusion_tag, 调用模板时报错.. 应该是路径 不对吧...我的templates 是放在app 目录下的.<待处理>
# 自定义模板标签. 标签的作用,在模板中 实现逻辑,如if ,for 等 from django.template import Library from datetime import datet ...