首页 > 代码库 > 代理模式-利用JDK原生动态实现AOP

代理模式-利用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工厂用于创建代理对象,使得我们运用更加方便。现在回想一下上面的应用场景,你是否有思路了呢?如果有思路了,不妨自己动手试试,加深对代理模式的理解,以便能更加深入理解后续知识。

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