了解代理模式这一篇文章就够了

基本介绍代理模式的核心思想就是:为一个对象(被代理对象)提供一个代理对象 , 并且通过代理对象控制对原来被代理对象的访问 。 可以简单理解为通过代理对象访问目标对象 。 这样做最大的好处就是可以在目标对象实现的基础上 , 增强额外的功能 , 起到扩展目标对象的效果 。
被代理的对象可以是远程对象、创建时开销大的对象、需要安全控制的对象等 。 实现代理模式有不同的形式 , 主要有:静态代理、动态代理(也被称为JDK代理或接口代理)、Cglib代理(不需要实现接口 , 在内存中动态创建代理对象) 。
单纯的通过文字描述大家可能对代理模式的理解还是不够深刻 , 我们可以通过一个简单的UML类图来加深对该模式的理解 。
代理模式UML类图:
了解代理模式这一篇文章就够了文章插图
UML类图讲解:
TargetObject:表示目标对象也就是被代理的对象 。 ProxyObject:代表的是代理对象 。 Client:代表客户端 , 使用代理对象的类 。
以上就是代理模式的一些基本概念 , 通过这些介绍相信大家对代理模式已经有了一个简单的认识 , 接下来就让菜鸟详细介绍一下上面提出的三种实现代理模式的方式 , 从而更加深入的了解代理模式 。
静态代理使用静态代理时需要让目标对象和代理对象一起实现相同的接口或者继承相同的父类 。 这样做的目的就是为了通过调用代理对象中和目标对象相同的方法来实现调用目标对象的方法 , 从而达到代理的效果 。
静态代理UML类图:
了解代理模式这一篇文章就够了文章插图
代码实现:
代理对象和目标对象实现的共同接口
public interface CommonInterface {void method();}目标对象
public class TargetObject implements CommonInterface {@Overridepublic void method() {System.out.println("被代理的类中的方法执行了!");}}代理对象
public class ProxyObject implements CommonInterface {// 通过接口聚合被代理的类private CommonInterface target;// 构造器public ProxyObject(CommonInterface target) {this.target = target;}@Overridepublic void method() {System.out.println("开始静态代理!");// 执行目标类的方法 。this.target.method();System.out.println("结束静态代理!");}}客户端测试类
public class Client {public static void main(String[] args) {TargetObject targetObject = new TargetObject();ProxyObject proxyObject = new ProxyObject(targetObject);proxyObject.method();}}【了解代理模式这一篇文章就够了】执行结果
了解代理模式这一篇文章就够了文章插图
总结
优点:实现起来简单 , 并且容易理解 , 只要确保目标对象和代理对象实现共同的接口或继承相同的父类就可以在不修改目标对象的前提下进行扩展 。
缺点:缺点也是显而易见的 , 必须有共同接口或父类 , 并且需要为每一个目标类维护一个代理类 , 当需要代理的类很多时会创建出大量代理类 。 一旦接口或父类的方法有变动 , 目标对象和代理对象都需要作出调整 。
这种方式虽说简单但是灵活性不足 。
动态代理(JDK代理、接口代理)使用JDK代理的基本前提是目标对象必须要实现接口 。 使用该方式代理对象是不需要手动编写代理类的 , 代理类是通过JDK的API动态的在内存中创建的 。
动态代理UML类图
了解代理模式这一篇文章就够了文章插图
代码实现JDK代理
目标对象需要实现的接口
public interface TargetInterface {void method();}目标对象
public class TargetObject implements TargetInterface {@Overridepublic void method() {System.out.println("被代理的类中的方法执行了!");}}代理工厂
public class ProxyFactory {// 目标对象private Object target;// 构造器public ProxyFactory(Object target) {this.target = target;}// 通过JDK的API在内存中动态生成一个代理对象 。public Object getProxyInstance() {/*** 参数介绍* ClassLoader loader:目标对象的类加载器* Class[] interfaces:目标对象实现的接口* InvocationHandler h:事件处理器 。 执行目标对象的方法时 ,*会触发该处理器中的invoke方法 。*/return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),/*** 此处用到了java8的Lambda表达式 。 看不太懂的有可以用传统方式 。* 传统方式:new InvocationHandler() { // 重写invoke方法 }** 参数说明:* Object proxy:代理类的实例* Method method:目标对象方法* Object[] args:目标对象方法入参*/(proxy, method, args) -> {System.out.println("JDK动态代理开始!");// 执行目标类的方法 。 returnVal是方法的返回值 , 没有返回值时为空 。Object returnVal = method.invoke(target, args);System.out.println("JDK动态代理结束!");return returnVal;});}}