BeanPostProcessor,后处理Bean,在applicationContext.xml中配置时,它将会作用于全部的目标类。
实现其作用于某个目标类可以使用“beanName”属性控制。
package com.spring.proxy;
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 {
/*if ("userDao".equals(beanName)) {
return bean;
}*/
System.out.println("初始化前" + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
/*if ("userDao".equals(beanName)) {
return bean;
}*/
System.out.println("初始化后" + beanName);
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("--------->开启事务" + bean.getClass().getName());
Object invoke = method.invoke(bean, args);
System.out.println("--------->关闭事务" + bean.getClass().getName());
return invoke;
}
});
}
}
以上执行步骤:
- 将userDao的实例对象传给后处理Bean,在其初始化前执行postPorcessorBeforeInitialization方法,打印了“初始化前userDao”;
- 初始化后执行postProcessorAfterInitialization方法;
- 在postProcessorAfterInitialization方法中先打印了“初始化后userDao”;
- 打印完文本后返回了userDao的代理对象;
- 其后userService重复userDao进行的步骤1、步骤2、步骤3,即在before方法中先打印“初始化前userService”,初始化时打印“初始化userServiceImpl”,最后在after方法中打印“初始化后userService”;
- 同时在after方法中返回userService的代理对象;
- 执行类TestClass中的ius.addUser()时,打印“------>开启事务com。。。UserServiceImpl”,然后调用bean(即UserServiceImpl)的addUser();
- 执行addUser方法中的iud.insert(),此时userDao的代理对象中的方法执行并打印“------>开启事务com。。。UserDaoImpl”,再调用其insert()方法打印“insert user into table successfully”,
- 。。。略
控制后处理Bean的作用目标,如上被注释代码,打开注释即可
TestClass代码:
package com.spring.proxy;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestClass {
@Test
public void test1() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
String xmlPath = "com/spring/proxy/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
IUserService ius = applicationContext.getBean("userService", IUserService.class);
ius.addUser();
applicationContext.getClass().getMethod("close").invoke(applicationContext);
}
}
UserServiceImpl代码:
package com.spring.proxy;
public class UserServiceImpl implements IUserService {
private IUserDao iud = null;
public void setIUserDao(IUserDao iud) {
this.iud = iud;
}
@Override
public void addUser() {
iud.insert();
}
public void myInitial() {
System.out.println("初始化UserServiceImpl");
}
public void myDestroy() {
System.out.println("销毁UserServiceImpl");
}
}
UserDaoImpl代码:
package com.spring.proxy;
public class UserDaoImpl implements IUserDao {
@Override
public void insert() {
System.out.println("insert user into table successfully");
}
}