springframework中的BeanPostProcessor(后处理bean)
2016-04-19 00:00
453 查看
摘要: spring提供勾子程序,用于运行时,修改spring创建bean实例,可以提供代理对象。用的是面向切面编程思想(aop).
这里的后处理bean的处理效果和spring aop(spring 面向切面编程)的效果一样.
spring提供后处理bean -- BeanPostProcessor接口
文档说明:Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
即spring提供勾子程序,用于运行时,修改spring创建bean实例,可以提供代理对象。用的是面向切面编程思想(aop).
这里的后处理bean的处理效果和spring aop(spring 面向切面编程)的效果一样.
那么后处理bean和spring aop区别?
后处理bean是spring基础核心部分,而spring aop编程是基于spring核心部分和aop联盟的思想的编程.
看看后处理bean与目标方法的执行过程
运行结果:
before BeanPostProcessor
after BeanPostProcessor
after BeanPostProcessor --- before target method
before BeanPostProcessor --- before target method
target method
before BeanPostProcessor --- after target method
after BeanPostProcessor --- after target method
由运行结果可知,程序会同时进入前后BeanPostProcessor,在环绕目标(around)执行相应程序
-----------------------------------------------------------------------------------------------------------------------------------------
整个目录工程如下, 完整代码在文章最后.
细节分析.
看看BeanPostProcessor 接口
我们让MyBeanPostProcessor 继承BeanPostProcessor
运行如下测试代码:
运行结果: 会报空指针异常.
将返回值两个都改为bean.
这时候可以正常运行.即真实对象会被传入自定义的后处理bean方法中.
在postProcessAfterInitialization方法中加入动态代理
运行结果:
目标方法前 -- 开启事务
target method
目标方法后 -- 提交事务
这里的Object obj = method.invoke(bean, args); 返回值obj是null,因为目标方法返回值类型是void.
--------------------------------------------------------------------------------------------------------------------------------------
全部代码
CategoryServcie
这里的后处理bean的处理效果和spring aop(spring 面向切面编程)的效果一样.
spring提供后处理bean -- BeanPostProcessor接口
文档说明:Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
即spring提供勾子程序,用于运行时,修改spring创建bean实例,可以提供代理对象。用的是面向切面编程思想(aop).
这里的后处理bean的处理效果和spring aop(spring 面向切面编程)的效果一样.
那么后处理bean和spring aop区别?
后处理bean是spring基础核心部分,而spring aop编程是基于spring核心部分和aop联盟的思想的编程.
看看后处理bean与目标方法的执行过程
package com.itheima.f_lifecycle_beanpost; 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;[由全限定类名可知,该对象是spring核心对象,而不是引入对象] public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { System.out.println("before BeanPostProcessor"); return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before BeanPostProcessor --- before target method"); //执行目标类的方法 Object obj = method.invoke(bean, args); System.out.println("before BeanPostProcessor --- after target method"); return obj; } }); } @Override public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("after BeanPostProcessor"); return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("after BeanPostProcessor --- before target method"); //执行目标类的方法 Object obj = method.invoke(bean, args); System.out.println("after BeanPostProcessor --- after target method"); return obj; } }); } }
运行结果:
before BeanPostProcessor
after BeanPostProcessor
after BeanPostProcessor --- before target method
before BeanPostProcessor --- before target method
target method
before BeanPostProcessor --- after target method
after BeanPostProcessor --- after target method
由运行结果可知,程序会同时进入前后BeanPostProcessor,在环绕目标(around)执行相应程序
-----------------------------------------------------------------------------------------------------------------------------------------
整个目录工程如下, 完整代码在文章最后.
细节分析.
看看BeanPostProcessor 接口
public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
我们让MyBeanPostProcessor 继承BeanPostProcessor
package com.itheima.f_lifecycle_beanpost; 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 { return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return null; }
运行如下测试代码:
package com.itheima.f_lifecycle_beanpost; import org.junit.Test; public class TestBeanPost { @Test public void demo01() throws Exception{ //spring 配置 String xmlPath = "com/itheima/f_lifecycle_beanpost/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); CategoryService categoryService = (CategoryService) applicationContext.getBean("categoryServiceId"); categoryService.addCategory(); } }
运行结果: 会报空指针异常.
将返回值两个都改为bean.
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
这时候可以正常运行.即真实对象会被传入自定义的后处理bean方法中.
在postProcessAfterInitialization方法中加入动态代理
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("后"); return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("目标方法前 -- 开启事务"); //执行目标类的方法 Object obj = method.invoke(bean, args); System.out.println("目标方法后 -- 提交事务"); return obj; } }); }
运行结果:
目标方法前 -- 开启事务
target method
目标方法后 -- 提交事务
这里的Object obj = method.invoke(bean, args); 返回值obj是null,因为目标方法返回值类型是void.
--------------------------------------------------------------------------------------------------------------------------------------
全部代码
CategoryServcie
package com.itheima.f_lifecycle_beanpost; public interface CategoryService { public void addCategory(); }
CategoryServiceImpl package com.itheima.f_lifecycle_beanpost; public class CategoryServiceImpl implements CategoryService { @Override public void addCategory() { System.out.println("target method"); } public void myInit(){ System.out.println("初始化"); } }
MyBeanPostProcessor package com.itheima.f_lifecycle_beanpost; 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 { // return bean; // } // // @Override // public Object postProcessAfterInitialization(Object bean, String beanName) // throws BeansException { // return bean; // } public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { System.out.println("before BeanPostProcessor"); return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before BeanPostProcessor --- before target method"); //执行目标类的方法 Object obj = method.invoke(bean, args); System.out.println("before BeanPostProcessor --- after target method"); return null; } }); } public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("after BeanPostProcessor"); return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("after BeanPostProcessor --- before target method"); //执行目标类的方法 Object obj = method.invoke(bean, args); System.out.println("after BeanPostProcessor --- after target method"); return obj; } }); } }
TestBeanPost
package com.itheima.f_lifecycle_beanpost; import org.junit.Test; public class TestBeanPost { @Test public void demo01() throws Exception{ //spring 配置 String xmlPath = "com/itheima/f_lifecycle_beanpost/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); CategoryService categoryService = (CategoryService) applicationContext.getBean("categoryServiceId"); categoryService.addCategory(); } }
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"> <bean id="categoryServiceId" class="com.itheima.f_lifecycle_beanpost.CategoryServiceImpl" /> <!-- <bean id="categoryServiceId" class="com.itheima.f_lifecycle_beanpost.CategoryServiceImpl" --> <!-- init-method="myInit" ></bean> --> <!-- 配置后处理bean,当前配置文件中的其他所有的bean都将生效 --> <bean class="com.itheima.f_lifecycle_beanpost.MyBeanPostProcessor"></bean> </beans>
相关文章推荐
- 浅谈JAVA中两种比较方式==和equals
- JAVA事务——事务特性
- 关于创建者模式
- JAVA关于GC的全部算法
- java override error
- Eclipse使用
- java事件适配器Adapter
- SpringMVC对于已经是json字符串的输出
- 关于JavaProcess的一些笔记
- [工作日志] LDAP的SHA加密方式--Java
- JAVA事务——事务的ACID特性
- UML类图中箭头和线条的含义和用法
- Java算法学习之旅-常用算法思想
- java访问修饰符
- 用IDEA 创建MAVEN 管理的 spring +springmvc + shiro项目
- Struts处理集合中的类型转换
- spring知识点积累2
- Java进阶学习第七天——泛型与反射回顾
- (java)从零开始之--装饰者设计模式
- 提高 MyEclipse 开发速度