百度推广登录网站,wordpress 页面很窄,在网站里文本链接怎么做,钦北区网站建设目录
什么是代理#xff1f;
代理模式
动态代理
Java中常用的代理模式
问题来了#xff0c;如何动态生成代理类#xff1f;
动态代理底层实现 什么是代理#xff1f; 顾名思义#xff0c;代替某个对象去处理一些问题#xff0c;谓之代理#xff0c;那么何为动态
代理模式
动态代理
Java中常用的代理模式
问题来了如何动态生成代理类
动态代理底层实现 什么是代理 顾名思义代替某个对象去处理一些问题谓之代理那么何为动态即让JVM虚拟机去完成而非程序员去完成与静态对比连起来就是让虚拟机去动态的创建一个对象去代替另一个对象完成某些业务需求 呢么其中就涉及到了两个对象代理类和目标类代理类又被前辈归纳成代理模式下面看代理模式
代理模式
代理模式是GoF23种设计模式之一。属于结构型设计模式。
代理模式的作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下一个客户不想或者不能直接引用一个对象此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用并且可以通过代理对象去掉客户不应该看到的内容和服务或者添加客户需要的额外服务。 通过引入一个新的对象来实现对真实对象的操作或者将新的对象作为真实对象的一个替身这种实现机制即为代理模式通过引入代理对象来间接访问一个对象这就是代理模式的模式动机。
代理模式中的角色
代理类代理主题目标类真实主题代理类和目标类的公共接口抽象主题客户端在使用代理类时就像在使用目标类不被客户端所察觉所以代理类和目标类要有共同的行为也就是实现共同的接口。 为什么要有个公共接口呢 呢你代理类要代替目标类完成某些操作你是不是就需要拥有目标类该有的功能如何拥有这个类拥有的功能呢一、代理类继承目标类但是继承太死板耦合度太高而且当需求量上去后你是不是要写n个子类不明智二、通过实现共同接口实现必要方法nice!!!完美解决 知道基本概念后我们完善一下用更加官方的话来表示。。。
动态代理
在程序运行阶段在内存中动态生成代理类被称为动态代理目的是为了减少代理类的数量。解决代码复用的问题。
Java中常用的代理模式
jdk动态代理cglib静态代理Javassist动态代理技术 我们主要分析JDK代理技术
JDK动态代理(理解):使用java反射包中的类和接口实现动态代理的功能,反射包java.lang.reflect,里面有三个类:InvocationHandlerMethodProxy | 下面我们通过一个实际业务需求来分析动态代理 | 假设某项目已上线并且运行正常只是客户反馈系统有一些地方运行较慢要求项目组对系统进行优化。于是项目负责人就下达了这个需求。首先需要搞清楚是哪些业务方法耗时较长于是让我们统计每个业务方法所耗费的时长。你坑定不能直接在已经上线并且运行很好的项目的源代码上操作啊于是乎我们采用静态代理方法代码如下
// 目标接口
public interface OrderService {void add();void update();void delete();
}
// 目标类
public class OrderServiceImpl implements OrderService {Overridepublic void add() {System.out.println(添加用户);}Overridepublic void update() {System.out.println(修改用户);}Overridepublic void delete() {System.out.println(删除用户);}
}
// 代理类
public class OrderServiceProxy implements OrderService {Overridepublic void add() {long begin System.currentTimeMillis();OrderService.add();long end System.currentTimeMillis();System.out.println(耗时(end - begin)毫秒);}Overridepublic void update() {long begin System.currentTimeMillis();OrderService.update();long end System.currentTimeMillis();System.out.println(耗时(end - begin)毫秒);}Overridepublic void delete() {long begin System.currentTimeMillis();OrderService.delete();long end System.currentTimeMillis();System.out.println(耗时(end - begin)毫秒);}
}在上面的静态代理方法中代理类和目标类都实现同一个接口在代理类中维护目标类对象并完成对目标类对象方法的增强这种方式虽然遵循开闭原则但是代理类和目标类至少是“一对一”的绑定关系如果需要被代理的目标类个数越多代理类就会越多会产生大量重复的代码也不利于后期的维护。
于是乎我们使用动态代理技术目前代码是这样的需要我们动态生成一个代理类
// 目标接口
public interfaceOrderService {void add();void update();void delete();
}
// 目标类
public class OrderServiceImpl implements OrderService {Overridepublic void add() {System.out.println(添加用户);}Overridepublic void update() {System.out.println(修改用户);}Overridepublic void delete() {System.out.println(删除用户);}
}
问题来了如何动态生成代理类
回归到文章中心题目JDK动态代理技术 在JDK中有一个Proxy类Proxy类是专门完成代理的操作类可以通过此类为一个或多个接口动态的生成实现类。这个类有一个静态方法newProxyInstance()方法。这个方法的目的就是给我们的目标对象返回一个代理对象。 我们可以看到其中newProxyInstance()方法有三个参数下面分析三个参数
第一个参数类加载器。在内存中生成了字节码要想执行这个字节码也是需要先把这个字节码加载到内存当中的。所以要指定使用哪个类加载器加载。第二个参数接口类型。代理类和目标类实现相同的接口所以要通过这个参数告诉JDK动态代理生成的类要实现哪些接口。第三个参数调用处理器。这是一个JDK动态代理规定的接口接口全名java.lang.reflect.InvocationHandler。显然这是一个回调接口也就是说调用这个接口中方法的程序已经写好了就差这个接口的实现类了。
所以接下来我们要写一下java.lang.reflect.InvocationHandler接口的实现类并且实现接口中的方法代码如下
public class TimerInvocationHandler implements InvocationHandler {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return null;}
}
InvocationHandler接口中有一个方法invoke这个invoke方法上有三个参数
第一个参数Object proxy。代理对象。设计这个参数只是为了后期的方便如果想在invoke方法中使用代理对象的话尽管通过这个参数来使用。第二个参数Method method。目标方法。第三个参数Object[] args。目标方法调用时要传的参数。
我们将来肯定是要调用“目标方法”的但要调用目标方法的话需要“目标对象”的存在“目标对象”从哪儿来呢我们可以给TimerInvocationHandler提供一个构造方法可以通过这个构造方法传过来“目标对象”代码如下
public class TimerInvocationHandler implements InvocationHandler {// 目标对象private Object target;// 通过构造方法来传目标对象public TimerInvocationHandler(Object target) {this.target target;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 目标执行之前增强。long begin System.currentTimeMillis();// 调用目标对象的目标方法Object retValue method.invoke(target, args);// 目标执行之后增强。long end System.currentTimeMillis();System.out.println(耗时(end - begin)毫秒);// 一定要记得返回哦。return retValue;}
}
接下来我们开始调用 // 创建目标对象OrderService target new OrderServiceImpl();// 创建代理对象OrderService orderServiceProxy (OrderService) ProxyUtil.newProxyInstance(target);// 调用代理对象的代理方法orderServiceProxy.add();orderServiceProxy.update();orderServiceProxy.delete(); 成功
动态代理底层实现
现在我们思考一个问题在使用动态代理之前我们有一个目标类、一个公共接口我们如何通过二者和proxy类返回一个代理类对象呢
我们知道创建一个对象就先要有这个类才能new对象那现在代理类都还不存在该怎么去构造代理对象呢
JDK动态代理的目的就是通过接口来生成代理类以及代理类的对象我们知道接口是不能直接通过new关键字创建对象的。那么JDK动态代理是怎么创建出代理类以及代理类对象的呢