开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天
JDK动态代理
默认情况下,Spring AOP使用JDK动态代理,JDK动态代理是通过java.lang.reflect.Proxy类实现的,可以调用Proxy类的newProxyInstance()方法创建代理对象。JDK动态代理可以实现无侵入式的代码扩展,并且可以在不修改源代码的情况下,增强某些方法。
实现过程演示:
第一步:
在IDEA中创建Maven项目,然后在其pom.xml文件中加载需要用到的Spring基础包和Spring依赖包(4+1)。
第二步:
创建接口UserDao,在UserDao接口中编写添加和删除的方法。
public interface UserDao{
public void addUser();
public void deleteUser();
}
第三步:
创建UserDao接口的实现类UserDaoImpl,分别实现接口中的方法。
public class UserDaoImpl implements UserDao{
public void addUser(){
System.out.println("添加用户");
}
public void deleteUser(){
System.out.println("删除用户");
}
}
第四步:
创建切面类MyAspect,该类中定义一个模拟权限检查的方法和一个模拟日志记录的方法,这两个方法就是切面中的通知。
//切面类:存在多个通知Advice(增强的方法)
public class MyAspect{
public void check_permissions(){
//权限检查
}
public void log(){
//记录日志
}
}
第五步:
创建代理类Myproxy,该类需要实现InvocationHandler接口设置代理类的调用处理程序。在代理类中,通过newProxyInstance()生成代理方法
public class MyProxy implements InvocationHandler{
private UserDao userDao;
public Object createProxy(UserDao userDao){
this.userDao = userDao;
ClassLoader classLoader = MyProxy.class.getClassLoader();//类加载器
Class[] classes = userDao.getClass().getInterfaces();//被代理对象实现的所有接口
return Proxy.newProxyInstance(classLoader, classes, this);//返回代理对象
}
/*
* 所有动态代理类的方法调用,都会交由invoke()方法去处理
* proxy 被代理的对象
* method 将要被执行的方法信息(反射)
* args 执行方法时所需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//创建切面对象
MyAspect myAspect = new MyAspect();
//前增强:权限检查
myAspect.check_Permissions();
//在目标类上调用方法,并传入参数,执行目标方法
Object obj = method.invoke(userDao, args);
//后增强:日志记录
myAspect.log();
return obj;
}
}
第六步: 测试
public class JDKTest{
public static void main(String[] args){
MyProxy jdkProxy = new Myproxy();
UserDaoImpl userDao = new UserDaoImpl();
//创建代理对象
UserDao userDao1 = (UserDao) jdkProxy.createProxy(UserDao);
//通过代理对象调用方法
userDao1.addUser();
userDao1.deleteUser();
}
}