动态代理步骤:
获取 RealSubject 上的所有接口列表;
确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX;
根据需要实现的接口信息,在代码中动态创建 该 Proxy 类的字节码;
将对应的字节码转换为对应的 class 对象;
创建 InvocationHandler 实例 handler,用来处理 Proxy 所有方法调用;
Proxy 的 class 对象 以创建的 handler 对象为参数,实例化一个 proxy 对象。
1. 实现代码
package com.jhlinux.clothes.common.dto;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface UserDao {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("添加功能");
}
@Override
public void delete() {
System.out.println("删除功能");
}
@Override
public void update() {
System.out.println("修改功能");
}
@Override
public void find() {
System.out.println("查找功能");
}
}
class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验");
Object result = method.invoke(target, args);
System.out.println("日志记录");
System.out.println();
return result;
}
}
public class Main {
public static void main(String[] args) throws Exception {
UserDao ud1 = new UserDaoImpl();
ud1.add();
ud1.delete();
ud1.update();
ud1.find();
System.out.println("----------");
UserDao ud2 = new UserDaoImpl();
MyInvocationHandler handler = new MyInvocationHandler(ud2);
UserDao ud2Proxy = (UserDao) Proxy.newProxyInstance(ud2.getClass().getClassLoader(), ud2.getClass().getInterfaces(), handler);
ud2Proxy.add();
ud2Proxy.delete();
ud2Proxy.update();
ud2Proxy.find();
}
}
2. 运行结果
3. 分析
动态代理主要就是对接口功能做增强来使用,可以参考AOP使用。本文使用基于jdk,也就是反射来实现。
参考文章:深入理解Java反射和动态代理