1、代理模式的概述
客户端通过代理对象渐渐与目标对象打交道,反之,目标对象委托代理对象与客户端进行交流。因此代理对象可以在目标对象方法前后,做出额外的操作,这就是代理AOP实现的原理。
2、原理图
3、模型图
4、静态代理代码演示
- (1)目标对象:
public class RealSubject implements Subject { @Override public void request() { System.out.println(" execute real subject request"); }}
- (2)代理对象:
public class Proxy implements Subject { private RealSubject realSubject; public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void request() { System.out.println(" before 织入逻辑"); try { realSubject.request(); } catch (Exception e) { System.out.println("ex:"+e.getMessage()); e.printStackTrace(); } finally { System.out.println(" after 织入逻辑"); } }}
- (3)客户端调用接口
public interface Subject { public void request();}
- (4)客户端调用
public class Client { public static void main(String[] args) { Subject subject = new Proxy(new RealSubject()); subject.request(); }}
5、动态代理代码演示
一、JDK代理
1、代理类
import cn.evchar.proxy.aop.RealSubject;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class JdkProxySubject implements InvocationHandler { private RealSubject realSubject; public JdkProxySubject(RealSubject realSubject) { this.realSubject = realSubject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object res = null; System.out.println("before"); try { res = method.invoke(realSubject,args); } catch (Exception e) { System.out.println("ex: "+e); throw e; } finally { System.out.println("after"); } return res; }}
2、客户端调用
import cn.evchar.proxy.aop.RealSubject;import cn.evchar.proxy.aop.Subject;import java.lang.reflect.Proxy;public class Client { public static void main(String[] args) { System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); Subject subject = (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{Subject.class},new JdkProxySubject(new RealSubject())); subject.request(); subject.hello(); }}
二、 cglib代理
1、代理类
import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class DemoMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("before in cglib"); Object res = null; try { res = methodProxy.invokeSuper(obj,args); } catch (Exception e) { System.out.println("ex "+ e); throw e; } finally { System.out.println("after in cglib"); } return res; }}
2、客户端调用
import cn.evchar.proxy.aop.RealSubject;import cn.evchar.proxy.aop.Subject;import net.sf.cglib.proxy.Enhancer;public class Client { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); // 目标对象 enhancer.setSuperclass(RealSubject.class); // 织入代码 enhancer.setCallback(new DemoMethodInterceptor()); // 生成 代理类 Subject subject = (Subject) enhancer.create(); subject.hello(); subject.request(); }}
6、Cglib 与JDK 动态代理比较
1、JDK只能针对有接口的类的接口方法进行动态代理
2、Cglib基于继承来实现代理,无法对static,final 类进行代理
3、Cglib基于继承来实现代理,无法对private,static 方法进行代理
4、反之JDK 不能对private 进行代理