JDK动态代理机制已经有文章写了,这里介绍Spring中的使用:
主要类:BeanPostProcessor
首先是一个接口:UserDao
package com.imooc.ioc.demo3;
public interface UserDao {
public void findAll();
public void save();
public void update();
public void delete();
}
下面是实现类:UserDaoImpl。配置文件中配置:
<bean id="userDao" class="com.imooc.ioc.demo3.UserDaoImpl"></bean>
package com.imooc.ioc.demo3;
public class UserDaoImpl implements UserDao {
@Override
public void findAll() {
System.out.println("查询");
}
@Override
public void save() {
System.out.println("保存");
}
@Override
public void update() {
System.out.println("修改");
}
@Override
public void delete() {
System.out.println("删除");
}
}
我们要对save方法进行增强,比如需要添加校验逻辑。这时需要定义一个继承BeanPostProcessor的类:
这里的BeanPostProcessor类是一个Bean后处理器,它是一个特殊的Bean。负责对容器中的其他Bean进行后处理。首先需要在配置文件中配置Bean后处理器
<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"></bean>
MyBeanPostProcessor:
package com.imooc.ioc.demo3;
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;
//实现BeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor{
//重写两个方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:初始化前方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("第八步:初始化后方法");
if("userDao".equals(beanName)){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println("权限校验======");
}
return method.invoke(bean,args);
}
});
return proxy;
}
return bean;
}
}
下面进行测试:
package com.imooc.ioc.demo3;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Bean作用范围测试
*/
public class SpringDemo3 {
@Test
public void demo(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)applicationContext.getBean("userDao");
userDao.findAll();
userDao.update();
userDao.save();
userDao.delete();
}
}
从测试结果可以看到,后处理器对目标类的指定方法进行了增强。