Spring Bean 后置处理器BeanPostProcessor
文章目录
- Spring Bean 后置处理器BeanPostProcessor
- BeanPostProcessor实现类代码演示
- BeanPostProcessor生成代理对象
Spring Bean 后置处理器BeanPostProcessor
Spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after()
可以配置多个 BeanPostProcessor 接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。
ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。
- Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
模拟
A a =new A();
a = B.before(a) —> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
a.init();
a = B.after(a);
a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)
a.destroy()
BeanPostProcessor实现类代码演示
BeanPostProcessor实现类1,同时实现getOrder方法来控制这些 执行顺序
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;public class PostProcessor implements BeanPostProcessor,Ordered {
//可以在初始化 bean 的之前和之后实现更复杂的逻辑。
//在Init-method的前后执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization1:" + beanName);
((InitHelloWorld)bean).getMessage();
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization1:" + beanName);
((InitHelloWorld)bean).getMessage();
return bean;
}
@Override
public int getOrder() {
return 0;
}
}
BeanPostProcessor实现类2
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;public class PostProcessor2 implements BeanPostProcessor,Ordered {
//可以在初始化 bean 的之前和之后实现更复杂的逻辑。
//在Init-method的前后执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization2:" + beanName);
((InitHelloWorld)bean).getMessage();
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization2:" + beanName);
((InitHelloWorld)bean).getMessage();
return bean;
}
@Override
public int getOrder() {
return 1;
}
}
配置
<?xml version=”1.0” encoding=”UTF-8”?>
<bean id="initHelloWorld" class="com.cc.study.lifecycle.InitHelloWorld"
init-method="init" destroy-method="destroy">
<property name="message" value="Hello World!"></property>
</bean>
<bean id="postProcessor" class="com.cc.study.lifecycle.PostProcessor"></bean>
<bean id="postProcessor2" class="com.cc.study.lifecycle.PostProcessor2"></bean>
</beans>
InitHelloWorld
public class InitHelloWorld{
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy(){
System.out.println("Bean will destroy now.");
}
}
测试
@Test
public void demo(){
String xmlPath = "lifecycle2.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
InitHelloWorld initHelloWorld = applicationContext.getBean("initHelloWorld",InitHelloWorld.class);
initHelloWorld.getMessage();
applicationContext.registerShutdownHook();
}
BeanPostProcessor生成代理对象
MyBeanPostProcessor
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;public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前方法 : " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("后方法 : " + beanName);
// bean 目标对象
// 生成 jdk 代理
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("------开启事务");
System.out.println("调用方法:" + method.getName());
//执行目标方法
Object obj = method.invoke(bean, args);
System.out.println("------提交事务");
return obj;
}});
}
}
配置
<?xml version=”1.0” encoding=”UTF-8”?>
BookDaoImpl
public class BookDaoImpl implements BookDao {
@Override
public void addBook() {
System.out.println("di add book");
}
}
测试
@Test
public void demo(){
String xmlPath = "lifecycle3.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
BookDao bookDao = applicationContext.getBean("bookDaoId",BookDao.class);
bookDao.addBook();
}
注意:
问题1:后处理bean作用某一个目标类,还是所有目标类?
所有
问题2:如何只作用一个?
通过“参数2”beanName进行控制
还没有评论,来说两句吧...