废话不多说,AOP的jdk代理案例就开始分步骤展示
效果:每次执行方法前和后都会执行各自的增强方法
准备工作:建立一个chapter03项目,新建一个包com.itheima.jdk。在WebContent的WEB-INF的lib导入Spring框架所需的包和第三方依赖包,并右键build path添加到项目中。
1、在包下新建一个UserDao接口,定义添加和删除方法
package com.itheima.jdk;
public interface UserDao {
public void addUser();
public void deleteUser();
}
2、在包下创建接口UserDao的实现类UserDaoImpl,实现接口中的方法。本案例的目标类为该类,即被增强的对象是UserDaoImpl。如果看不懂,建议先了解面向切面编程的相关术语后再来看该案例。
package com.itheima.jdk;
import org.springframework.stereotype.Repository;
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
3、在新建包com.itheima.aspect下创建切面类,名为MyAspect。定义一个方法来模拟权限检查,定义一个方法来模仿记录日志。
package com.itheima.aspect;
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟检查权限。。。");
}
public void log() {
System.out.println("模拟记录日志。。。");
}
}
4、在jdk原包下创建代理类JdkProxy,该类需要实现接口InvocationHandler,编写其中的代理方法
package com.itheima.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.itheima.aspect.MyAspect;
public class JdkProxy implements InvocationHandler{
// 声明目标类接口
private UserDao userDao;
// 创建代理方法
public Object createProxy(UserDao userDao1) {
userDao = userDao1;
// 1.类加载器
ClassLoader classLoader = JdkProxy.class.getClassLoader();
// 2.被代理对象实现的所有接口
Class[] clazz = userDao.getClass().getInterfaces();
// 3.使用代理类,进行增强,返回的是代理类的对象
return Proxy.newProxyInstance(classLoader, clazz,this);
}
@Override
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;
}
}
增强后返回代理类对象的方法,即Proxy类下的newProxyInstance(当前类的类加载器, 被代理对象的所有接口,this)中,参数this是代理类JdkProxy本身。method.invoke(),只知道是调用了目标类的对象。知其然不知其所以然,需要查阅底层实现了,有大佬请赐教
5、在原包下创建测试类JdkTest
package com.itheima.jdk;
public class JdkTest {
public static void main(String[] args) {
// 创建代理对象
JdkProxy jdkProxy = new JdkProxy();
// 创建目标对象
UserDao userDao = new UserDaoImpl();
// 从代理对象中获取增强后的目标对象
UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}