Java代理 - Proxy
1.理论
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
代理也称“委托”,分为静态代理和动态代理,代理模式也是常用的设计模式之一,具有方法增强、高扩展性的设计优势。
2.分类
静态代理:编译期已经确定被代理的对象和代理类;实现简单且不侵入原代码,当接口改动时,需要同时修改代理类,不易维护。
动态代理:在运行期间才确定被代理的对象,并动态生成一个代理类;对比静态代理,对代理类统一处理,而不用修改每个代理类。
- JDK动态代理(接口代理):通过JAVA反射来创建代理类(反射机制在生成类的过程中比较高效)。被代理类和代理类实现同样的接口,实现 InvokecationHandler接口。
- CGLIB动态代理(子类代理):通过ASM编辑字节码文件来生成一个代理类(ASM在生成类之后的相关执行过程中比较高效)。生成的代理类继承被代理类,实现 MethodInterceptor接口。
3.实现
静态代理:
// 接口 public interface StaticProxyInterface { void work(); } // 目标对象:要被代理的类实现接口 public class TargetObject implements StaticProxyInterface{ @Override public void work() { System.out.println("开始搬砖..."); } } // 代理类 public class StaticProxyObject implements StaticProxyInterface{ private TargetObject targetObject; // 通过构造方法注入目标真实对象 public StaticProxyObject(TargetObject targetObject) { this.targetObject = targetObject; } @Override public void work() { clock(); targetObject.work(); } //增强方法 private void clock(){ System.out.println("打卡..."); } } // 测试 public static void main(String[] args) { StaticProxyInterface staticProxyInterface = new StaticProxyObject(new TargetObject());
System.out.println(staticProxyInterface.getClass()); staticProxyInterface.work(); }
class com.yue.proxy.StaticProxyObject 打卡... 开始搬砖...
JDK动态代理:
// 接口 public interface SubjectInterface { void work(); } // 目标对象:要被代理的类实现接口 public class TargetObject implements SubjectInterface{ @Override public void work() { System.out.println("开始搬砖..."); } } // JDK动态代理类 public class JDKProxyObject implements InvocationHandler { private SubjectInterface target; // 通过构造方法注入目标真实对象 public JDKProxyObject(SubjectInterface target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { clock(); return method.invoke(target, args); } private void clock(){ System.out.println("打卡..."); } } // 测试 public static void main(String[] args) { SubjectInterface subjectInterface = new TargetObject(); JDKProxyObject jdkProxyObject = new JDKProxyObject(subjectInterface); SubjectInterface subject = (SubjectInterface) Proxy.newProxyInstance(jdkProxyObject.getClass().getClassLoader(),subjectInterface.getClass().getInterfaces(),jdkProxyObject); System.out.println(subject.getClass()); subject.work(); } // 输出内容 class com.sun.proxy.$Proxy0 打卡... 开始搬砖...
Cglib动态代理
// 目标对象:要被代理的类 public class TargetObject { public void work() { System.out.println("开始搬砖..."); } } // 使用 Cglib 代理 public class CglibProxyObject implements MethodInterceptor { public Object getProxyInstance(Class clazz){ // 创建一个工具类 Enhancer enhancer = new Enhancer(); // 设置父类 enhancer.setSuperclass(clazz); // 设置回调函数 enhancer.setCallback(this); // 创建子类对象,即代理对象 return enhancer.create(); } // 拦截方法 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { clock(); return methodProxy.invokeSuper(o, objects); } private void clock(){ System.out.println("打卡..."); } } public static void main(String[] args) { TargetObject cglibProxy = (TargetObject)new CglibProxyObject().getProxyInstance(TargetObject.class); System.out.println(cglibProxy.getClass()); cglibProxy.work(); } // 输出内容 class com.yue.proxy.TargetObject$$EnhancerByCGLIB$$8e8022b6 打卡... 开始搬砖...

浙公网安备 33010602011771号