代理模式-利用JDK原生动态实现AOP

一、目录

二、概述与模型

1、概述

  含义:控制对对象的访问。

  作用:详细控制某个(某类)某对象的方法,在调用之前做前置处理,调用之后做后置处理,从而实现将统一流程代码放在代理类中处理。

  举例:我们在学习JDBC的时候,在批量处理的时候遇到过事务。流程:设置提交方式为手动提交-开启事务-批量处理-关闭事务-设置提交方式为默认。从这里我们清晰可以看见,每次进行批处理的时候,唯有增删改操作变化,其他的操作都是一样的。那么,我们可不可以把一样的操作提取出来交给一个类处理,批量操作提取出来交给一个类实现?带着疑问,我们来看一下代理模式的模型,你就有所明白了。

2、模型

  

  Subject(抽象角色):定义代理角色和真实角色的公共对外方法。

  RealSubject(真实角色):实现抽象角色,定义真实角色所要实现的真实业务逻辑,供代理角色调用。

  Proxy(代理角色):实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

  最终目标:将统一的流程控制放到代理角色处理。

三、应用场景描述

  1、安全代理:屏蔽对真实角色的直接访问,由代理角色控制,等业务真实需要的时候,才由代理对象调用真实对象方法。

  2、远程代理:通过代理类处理远程方法调用(RMI)。

  3、延迟代理:先加载轻量级的代理对象,真正需要再加载真实对象。例如加载图片、视频,先由代理对象在后台开启流对象,待真正需要浏览图片、视频的时候,才由真实对象加载图片,最后由代理对象关闭流对象。

  4、事务:解决概述举例内容,一层不变的内容由代理对象承担,而真正的业务逻辑由真实对象的方法实现。

  5、真实系统的日志处理、JDBC事务、Connection的开启与关闭。

  代码演示场景描述:假设一个明星被邀请去拍广告、拍电影,那么务必有这些流程:面谈->起草合同->安排机票、车票->出席活动->结算尾款。假设一年拍一两次广告,那么完全由一个明星自己解决。事实上,每个明星都有经纪人,而明星只专心负责出席活动,其他事务由经纪人操作。

  

四、静态代理实现

1、抽象角色

2 public interface Star {
3     //出席拍电影
4     public void play();
5     //出席拍广告
6     public void advertise();
7 }

2、真实角色

 1 public class RealStar implements Star {
 2
 3     public void play() {
 4         System.out.println("RealStar拍电影!");
 5     }
 6
 7     public void advertise() {
 8         System.out.println("RealStar拍广告!");
 9     }
10
11 }

3、代理角色

public class ProxyStar implements Star{
    Star star;

    public ProxyStar(){}

    public ProxyStar(Star star) {
        this.star = star;
    }

    //面谈
    public void interview() {
        System.out.println("ProxyStar interview");
    }

    //安排机票车辆
    public void creatingContract() {
        System.out.println("ProxyStar creatingContract");
    }

    //出席演唱会
    public void arrange() {
        System.out.println("ProxyStar arrange");
    }

    public void play() {
        System.out.println("#############");
        //面谈
        interview();
        //合同起草
        creatingContract();
        //安排机票车辆
        arrange();
        //出席演唱会
        star.play();
        //收尾款
        closeout();
    }

    public void advertise() {
        System.out.println("#############");
        //面谈
        interview();
        //合同起草
        creatingContract();
        //安排机票车辆
        arrange();
        //出席演唱会
        star.advertise();
        //收尾款
        closeout();
    }

    //收尾款
    public void closeout() {
        System.out.println("ProxyStar closeout");
    }
}

4、客户端测试

 1 public class Client {
 2     public static void  main(String [] args){
 3         //真实明星王宝强
 4         Star realStar=new RealStar();
 5         //经纪人
 6         Star proxyStar=new ProxyStar(realStar);
 7         //邀约拍电影
 8         proxyStar.play();
 9         //邀约拍广告
10         proxyStar.advertise();
11     }
12 }

5、测试结果

  

五、动态代理实现

1、抽象角色、真实角色跟静态代理一致。

2、StarHandler

 1 public class StarHandler implements InvocationHandler {
 2
 3     Star star;
 4     public StarHandler(Star star){
 5         this.star=star;
 6     }
 7     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 8         Object object=null;
 9         System.out.println("###############");
10         System.out.println("面谈!");
11         System.out.println("起草合同。");
12         System.out.println("安排机票。");
13         if("play".equals(method.getName())||"advertise".equals(method.getName())){
14             object=method.invoke(star,args);
15         }
16         System.out.println("收尾款。");
17         return object;
18     }
19 }

3、客户端调用

public class Client {
    public static void  main(String [] args){
        //真实明星王宝强
        Star realStar=new RealStar();
       //动态处理类
        StarHandler handler=new StarHandler(realStar);
        //获得经纪人
        Star proxy= (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),realStar.getClass().getInterfaces(),handler);

        //出席拍电影
        proxy.play();
        //出席拍广告
        proxy.advertise();
    }
}

4、测试结果

六、结合注解模拟AOP

1、抽象角色

public interface Star {
    //出席拍电影
    @DoOddJob("play")
    public void play();

    //出席拍广告
    @DoOddJob("advertise")
    public void advertise();

}

2、真实角色

 1 public class RealStar implements Star {
 2
 3     public void play() {
 4         System.out.println("RealStar拍电影!");
 5     }
 6
 7     public void advertise() {
 8         System.out.println("RealStar拍广告!");
 9     }
10
11 }

3、StarHandler

public class StarHandler implements InvocationHandler {
    //目标对象:真正的对象
    Object targetObject;
    InvocationHandler handler;
    public StarHandler(Object object){
        this.targetObject=object;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object object=null;

        System.out.println("###############");
        DoOddJob annotation=method.getAnnotation(DoOddJob.class);
        System.out.println(annotation);
        System.out.println("面谈!");
        System.out.println("起草合同。");
        System.out.println("安排机票。");
        if(annotation.value().equals(method.getName())){
            object=method.invoke(targetObject,args);
        }
        System.out.println("收尾款。");
        return object;
    }

    public Object createProxy(){
        return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),targetObject.getClass().getInterfaces(),this);
    }
}

4、自定义注解

1 @Target({ElementType.METHOD,ElementType.TYPE})
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface DoOddJob {
4     String value() default "";
5 }

5、客户端调用

 1 public class Client {
 2     public static void  main(String [] args){
 3         //真实明星王宝强
 4         Star realStar=new RealStar();
 5        //动态处理类
 6         StarHandler handler=new StarHandler(realStar);
 7         //获得经纪人
 8         Star proxy= (Star) handler.createProxy();
 9
10         //出席拍电影
11         proxy.play();
12         //出席拍广告
13         proxy.advertise();
14     }
15 }

6、测试结果

六、回顾

1、代理模式是什么?代理模式有什么用?

  为了统一的流程控制,剔除重复的操作交由代理角色,真实角色负责真正的业务操作。

2、静态代理与动态代理的区别?

  动态代理相对于静态代理,变得更加灵活,同时利用Java的动态性(反射、字节码操作、动态编译)处理更加容易。

  优点:抽象角色中(接口)生命的所有方法都被转移到调用处理器一个集中的方法处理,这样处理起来解耦,便于扩展,更加灵活。

3、进一步思考

  AOP核心就是在真正业务前后添加一些统一流程(由代理对象实现)。同时,利用反射或者注解,便于获取参数,从而更加灵活。甚至,我们还可以做一个Handler工厂用于创建代理对象,使得我们运用更加方便。现在回想一下上面的应用场景,你是否有思路了呢?如果有思路了,不妨自己动手试试,加深对代理模式的理解,以便能更加深入理解后续知识。

时间: 2024-08-06 18:46:31

代理模式-利用JDK原生动态实现AOP的相关文章

设计模式三: 代理模式(Proxy) -- JDK的实现方式

设计模式三: 代理模式(Proxy) -- JDK的实现方式 简介 代理模式属于行为型模式的一种, 控制对其他对象的访问, 起到中介作用. 代理模式核心角色: 真实角色,代理角色; 按实现方式不同分为静态代理和动态代理两种; 意图 控制对其它对象的访问. 类图 实现 JDK自带了Proxy的实现, 下面我们先使用JDK的API来演示代理如何使用, 随后再探究Proxy的实现原理,并自己来实现Proxy. JDK代理类的使用: (InvocationHandler,Proxy) 使用JDK实现的代

代理模式(静态、动态)

代理模式的使用价值还是挺高的,各种框架中都用到了.把基础认真看看,学框架的时候也容易了. 关于静态代理: 代理模式的应用场景: 如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法: 1.修改原有的方法来适应.这样违反了“对扩展开放,对修改关闭”的原则. 2.就是采用一个代理类调用原有的方法,且对产生的结果进行控制.这种方法就是代理模式. 使用代理模式,可以将功能划分的更加清晰,有助于后期维护! 代理模式的要点: 1.“增加一层间接层”是软件系统中对许多负责问题的一种常见解决方法.

两种代理模式(JDK和Cglib)实例

CGlib代理模式: package CGLIB; import java.lang.reflect.Method; import JDK.Test; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib动态代理 * * @author student * */ public clas

设计模式 - 代理模式(jdk)

定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问. 一.静态代理 静态代理说白了就是把原先直接调用被代理类的方法放到代理类来调用,同时 我们可以在代理类额外的添加一些操作. 接口: package com.proxy.example; public interface Employ { void work(); } 实现: package com.proxy.example; public class Engineer implements Employ { @Override pu

代理模式(Java的动态代理)

(一)是什么?what? ①:定义: ②:特征:1.0代理类(中间追求者),与委托类(追求者)有同样的接口: 2.0代理类--->主要负责为委托类预处理消息.过滤消息.把消息传递给委托类,事后处理消息等.[类似:帮别人追女朋友,打探消息]. 3.0代理类与委托类之间通常会有 关联关系 [类似哥们儿].一个代理类的对象 与 一个委托类的对象关联.代理类本身不真正实现服务,而是通过调用委托类的方法,来提供特定服务.[类似于帮追的哥们  是  根据  喜欢那女孩儿的哥们儿  的要求  来做事儿]. ③

谈谈Java的代理模式及动态代理

Java的动态代理在实践中有着广泛的使用场景,比如最场景的Spring AOP.Java注解的获取.日志.用户鉴权等.本篇文章带大家了解一下代理模式.静态代理以及基于JDK原生动态代理. 代理模式无论学习静态代理或动态代理,我们都要先了解一下代理模式. 先看百度百科的定义: 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 直接看定义可能有些难以理解,我们就以生活中具体的实例

Java-马士兵动态代理模式

Java-马士兵动态代理模式 模拟jdk的动态代理的实现原理, 这些东西没有必要写出来,写项目的时候用不上,主要是面试和理解原理: ? 有些工具可以直接生成二进制码,没有必要生成文件. 代理模式-聚合与继承方式比较 参考地址:http://www.cnblogs.com/shamgod/p/4591782.html ? 一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,

"围观"设计模式(12)--结构型之代理模式(Proxy Pattern)

维基百科 代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式. 所谓的代理者是指一个类可以作为其它东西的接口.代理者可以作任何东西的接口:网络连接.内存中的大对象.文件或其它昂贵或无法复制的资源.----WIKIPEDIA 个人理解 代理模式就是找另外的一个对象作为代理去为你实施请求,代理模式分为两种,一种是静态代理模式,另外一种是动态代理模式,静态代理模式是代理类为其创建一个对象,将需要代理的类的对象赋予代理类中的该对象,让代理类中该对象去代替需要代理的类的对象去执行一定的

动态代理模式--源码分析

Proxy源码 1,成员变量 ?代理类的构造函数参数.默认每个代理类都具有一个invocationHandler的构造方法.(本文代码主要基于jdk 1.7) /** parameter types of a proxy class constructor */ private static final Class<?>[] constructorParams = { InvocationHandler.class }; ?缓存代理对象. private static final WeakCa