AOP编程—JDK动态代理
maven配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
JDK动态代理
spring是aop的一种实现框架,spring默认使用jdk动态代理。是面向接口的开发
- 定义接口
UserDao
package edu.abc.jdk;
public interface UserDao {
public void addUser();
public void deleteUser();
}
- 实现接口
UserDaoImp
package edu.abc.jdk;
public class UserDaoImp implements UserDao {
public void addUser() {
// TODO 自动生成的方法存根
System.out.println("添加用户");
}
public void deleteUser() {
// TODO 自动生成的方法存根
System.out.println("删除用户");
}
}
- 定义切面编程
package edu.com.aspect;
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟查询权限");
}
public void log() {
System.out.println("模拟记录日志");
}
}
- 创建代理类
JdkProxy
该类需要实现
invocationHandler
接口,并编写代理方法。需要通过Proxy
类实现动态代理。
package edu.abc.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mysql.jdbc.authentication.MysqlClearPasswordPlugin;
import edu.com.aspect.MyAspect;
public class jdkProxy implements InvocationHandler {
private UserDao userDao;
// 创建代理方法
public Object createProxy(UserDao userDao) {
this.userDao=userDao;
// classLoader用处: 想在a.java运行前,执行打印日志,先获取a.class,先执行打印日志任务,再执行a.class
ClassLoader classLoader = jdkProxy.class.getClassLoader(); // 代理对象类加载器
// 获取目标对象的所有接口,以此判断代理对象在调用代理对象的方法是否存在。
Class[] clazz=userDao.getClass().getInterfaces(); // 目标对象的所有接口
return Proxy.newProxyInstance(classLoader, clazz, this); // 当前代理对象
}
/* 代理对象调用方法时,可以理解为调用的是当前方法,
** proxy 被代理后的对象、当前的代理对象
** method 调用的方法(目标对象中的方法)
** args 执行method需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO 自动生成的方法存根
// 模拟操作
if(method.getName().equals('addUser')){
System.out.println('执行的方法为:'+method.getName())
}
MyAspect myAspect = new MyAspect();
myAspect.check_Permissions();
Object object=method.invoke(userDao, args);
// 反射机制运行方法, userDao为目标对象,
// 实质上代理对象执行目标对象的方法,是通过新建一个目标对象,去执行要执行的方法
myAspect.log();
return object;
}
}
- 测试类
JdkTest
package edu.abc.jdk;
public class JdkTest {
public static void main(String[] args) {
// TODO 自动生成的方法存根
jdkProxy jp=new jdkProxy();
UserDao userDao=new UserDaoImp();
UserDao userDao2=(UserDao) jp.createProxy(userDao);// 从代理对象中获取增强的目标对象
userDao2.addUser(); // 执行的是代理对象的invoke方法
userDao2.deleteUser();
}
}
- 运行结果
addUser
模拟查询权限
添加用户
模拟记录日志
模拟查询权限
删除用户
模拟记录日志