您的位置:首页 > 编程语言 > Java开发

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与目标方法的执行过程

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: