JavaWeb学习笔记之动态代理

    xiaoxiao2021-03-25  66

    代理是实现AOP(Aspect oriented program,面向切面编程)的核心和关键技术。

    1.什么是代理(proxy)?

    代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类负责为委托类预处理消息,过滤消息并转发消息以及进行消息被委托类执行后的后续处理。为了保持行为的一致性,代理类和委托类通常会实现相同的接口

    静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,也就是说在程序运行前代理类的.class文件就已经存在。动态代理:在程序运行时运用反射机制动态创建生成。

    紫色线代表继承关系,红色线代表调用关系

    2. 动态代理

    JVM可以在运行期动态生成类的字节码,该类往往被用作动态代理类。JVM生成的动态类必须实现一个或多个接口,所以这种只能用作具有相同接口的目标类的代理。CGLIB库可以动态生成一个类的子类,一个类的子类也可作为该类的代理,这个可用来为没有实现接口的类生成动态代理类。代理类可在调用目标方法之前、之后、前后、以及处理目标方法异常的catch块中添加系统功能代码。

    3. 创建代理对象

    创建代理对象的作用:动态地生成一个类,该类实现了A,B接口,然后创建该类的对象。 需要创建出一个新类,被ClassLoader加载进方法区。

    Proxy.newProxyInstance()方法的三大参数: 1. ClassLoad: 2. Class[] interfaces:需要实现的接口们 3. InvocationHandler: 每次调用都会执行invoke()方法内的代码

    //参数一 ClassLoader loader=this.getClass().getClassLoader(); //参数二 Class[] interfaces={A.class,B.class}; //参数三 InvocationHandler invocationHandler=new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invocation"); return null; } }; //创建一个实现了A接口和B接口的代理对象 Object proxy= Proxy.newProxyInstance(loader,interfaces,invocationHandler); //强转 A a=(A)proxy; B b=(B)proxy; System.out.println(proxy.getClass().getName());

    InvocationHandler接口只有一个invoke方法,每次调用代理类的方法,即调用了InvocationHandler对象的invoke方法

    invoke方法涉及三个要素:

    代理对象代理对象调用的方法方法接受的参数 注:Object类的hashCode,equals,toString方法交给invoke,其他的Object类的方法,Proxy有自己的实现。

    4.实现一个代理工厂模式

    需求:男服务员实现服务员接口,在进行服务员的所有方法时,都被beforeAdvice和AfterAdvice装饰

    /**@author * 用来生成代理对象 * 它需要所有的参数: * 1.目标对象 * 2.增强内容 * * 代理工厂使用过程: * * 1.创建代理工厂 * 2.设置三个成员变量: * 目标对象 * 前置增强 * 后置增强 * 3.调用getProxy得到代理对象 * 执行代理对象的方法时: * 执行BeforeAdvice的before() * 执行目标对象的目标方法 * 执行AfterAdvice的after() */ public class ProxyFactory { private Object targetObject;//目标对象 private BeforeAdvice beforeAdvice; private AfterAdvice afterAdvice; //用来生成代理对象 public Object getProxy(){ //给出创建Proxy对象的三大参数 ClassLoader classLoader=this.getClass().getClassLoader(); Class[] interfaces=targetObject.getClass().getInterfaces(); InvocationHandler h=new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用代理对象的方法时会执行这里的内容 if (beforeAdvice!=null){ beforeAdvice.before(); } Object res=method.invoke(targetObject,args); if (afterAdvice!=null) afterAdvice.after(); return res; } }; Object proxyObject= Proxy.newProxyInstance(classLoader,interfaces,h); return proxyObject; } public Object getTargetObject() { return targetObject; public interface Waiter { public void serve(); public void washing(); public void cashing(); } public class ManWaiter implements Waiter { @Override public void serve() { System.out.println("serving"); } @Override public void washing() { System.out.println("washing dishes"); } @Override public void cashing() { System.out.println("cashing money"); } } public interface BeforeAdvice { public void before(); } public interface AfterAdvice { public void after(); }

    运行:

    public class demo { public static void main(String[] args) { ProxyFactory factory=new ProxyFactory(); factory.setTargetObject(new ManWaiter()); factory.setBeforeAdvice(new BeforeAdvice() { @Override public void before() { System.out.println("this is before ........."); } }); factory.setAfterAdvice(new AfterAdvice() { @Override public void after() { System.out.println("this is after"); } }); Waiter waiter= (Waiter) factory.getProxy(); waiter.serve(); waiter.washing(); waiter.cashing(); } }

    输出:

    this is before ……… serving this is after this is before ……… washing dishes this is after this is before ……… cashing money this is after

    转载请注明原文地址: https://ju.6miu.com/read-35181.html

    最新回复(0)