zoukankan      html  css  js  c++  java
  • 设计模式之禅之代理模式

    jdk的动态代理的条件:

    ===>要实现动态代理的首要条件是:被代理类必须实现一个接口,回想一下前面的分析吧。当然了,现在也有很多技术如CGLIB可以实现不需要接口也可以实现动态代理的方
    式。

    动态代理的应用

    代理模式应用得非常广泛,大到一个系统框架、企业平台,小到代码片段、事务处理,稍不留意就用到代理模式。可能该模式是大家接触最多的模式,而且有了AOP大家写代理就
    更加简单了,有类似Spring AOP和AspectJ这样非常优秀的工具,拿来主义即可!不过,大家可以看看源代码,特别是调试时,只要看到类似$Proxy0这样的结构,你就应该知道这是一
    个动态代理了。友情提醒,在学习AOP框架时,弄清楚几个名词就成:切面(Aspect)、切入点(JoinPoint)、通知(Advice)、织入(Weave)就足够了,理解了这几个名词,应用时你
    就可以游刃有余了!

    (1)普通代理,代理和被代理实现相同的接口。代理者拥有被代理者的引用

    一:接口

     1 package com.nonbank.commons.aop;
     2 /**
     3  * 接口类
     4  * @author sxf
     5  *
     6  */
     7 public interface Player {
     8     /**
     9      *打怪升级
    10      */
    11     public void killBoss();
    12 }
    View Code

    二:被代理者

     1 package com.nonbank.commons.aop;
     2 /**
     3  * 真实玩家
     4  * @author sxf
     5  *
     6  */
     7 public class GamePlayer implements Player{
     8 
     9     @Override
    10     public void killBoss() {
    11         System.out.println("GamePlayer.killBoss()=======>打死一个boss");
    12     }
    13     
    14     
    15 
    16 }
    View Code

    三:代理者

     1 package com.nonbank.commons.aop;
     2 
     3 import org.drools.rule.builder.dialect.java.parser.JavaParser.parExpression_return;
     4 
     5 /**
     6  * 代理玩家
     7  * @author sxf
     8  *
     9  */
    10 public class GamePlayer_Poxy implements Player {
    11     
    12     
    13     
    14     /**
    15      * 被代理的玩家
    16      */
    17     private Player player;
    18     
    19     
    20      public GamePlayer_Poxy() {
    21         
    22     }
    23      
    24      public GamePlayer_Poxy(GamePlayer player) {
    25         this.player=player;
    26     }
    27     
    28     @Override
    29     public void killBoss() {
    30         System.out.println("GamePlayer_Poxy.killBoss()===>代理实现的一些增强前");
    31         player.killBoss();
    32         System.out.println("GamePlayer_Poxy.killBoss()===>代理实现的一些增强后");
    33         
    34     }
    35 
    36     
    37 }
    View Code

    四:测试类

     1 package com.nonbank.commons.aop;
     2 
     3 public class AopTest {
     4 
     5     public static void main(String[] args) {
     6         
     7     }
     8     
     9     /**
    10      * 普通的静态代理
    11      */
    12     public static void test01(){
    13         //被代理角色
    14         GamePlayer gamePlayer=new GamePlayer();
    15         //代理角色
    16         GamePlayer_Poxy poxy=new GamePlayer_Poxy(gamePlayer);
    17         //代理角色持有被代理角色的引用,代理和被代理实现相同的接口
    18         poxy.killBoss();
    19     }
    20     
    21 }
    View Code

    (2)动态代理,代理指定接口的实现

    一:接口

     1 package com.nonbank.commons.aop;
     2 /**
     3  * 动态代理,被代理的接口
     4  * @author sxf
     5  *
     6  */
     7 public interface Mlayer {
     8     /**
     9      * 打怪
    10      * @param name
    11      * @return
    12      */
    13     public String killBoss(String name);
    14     /**
    15      * 登陆
    16      * @param name
    17      * @param password
    18      * @return
    19      */
    20     public String login(String name,String password);
    21 }
    View Code

    二:动态代理执行器,也就是在此处添加增强的实现类

     1 package com.nonbank.commons.aop;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 /**
     6  * 动态代理的增强类,实现代理的类
     7  * @author sxf
     8  *
     9  */
    10 public class MyInvocationHandler implements InvocationHandler{
    11     /**
    12      * 被代理的真实对象
    13      */
    14     private Object target;
    15     
    16     
    17     
    18     public MyInvocationHandler() {
    19         
    20     }
    21     
    22     public MyInvocationHandler(Object target){
    23         this.target=target;
    24     }
    25 
    26     @Override
    27     public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
    28         System.out.println("MyInvocationHandler.invoke()===>动态代理实现了一些增强前..................");
    29         Object object=method.invoke(this.target, args);
    30         System.out.println("MyInvocationHandler.invoke()===>动态代理实现了一些增强后..................");
    31         return object;
    32     }
    33     
    34 
    35 }
    View Code

    三:被代理者的实现类

     1 package com.nonbank.commons.aop;
     2 /**
     3  * 动态代理被代理者
     4  * @author sxf
     5  *
     6  */
     7 public class SxfGamePlayer  implements Mlayer{
     8 
     9     
    10     @Override
    11     public String killBoss(String name){
    12         System.out.println("SxfGamePlayer.killBoss()要打的怪物名字是===>"+name);
    13         return name+"这个怪物被打死了";
    14     }
    15 
    16     @Override
    17     public String login(String name, String password) {
    18         System.out.println("SxfGamePlayer.login()登陆的名字是===>name=["+name+"]password=["+password+"]");
    19         return "sxf你登陆成功了";
    20     }
    21     
    22     
    23 
    24     
    25 }
    View Code

    四:测试类

     1 package com.nonbank.commons.aop;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 public class AopTest {
     6 
     7     public static void main(String[] args) {
     8         test02();
     9     }
    10     
    11     /**
    12      * 普通的静态代理
    13      */
    14     public static void test01(){
    15         //被代理角色
    16         GamePlayer gamePlayer=new GamePlayer();
    17         //代理角色
    18         GamePlayer_Poxy poxy=new GamePlayer_Poxy(gamePlayer);
    19         //代理角色持有被代理角色的引用,代理和被代理实现相同的接口
    20         poxy.killBoss();
    21     }
    22     
    23     /**
    24      * 动态代理测试
    25      */
    26     public static void test02(){
    27         //被代理对象的真实角色
    28         SxfGamePlayer paGamePlayer=new SxfGamePlayer();
    29         //生成代理执行的Handler
    30         MyInvocationHandler myInvocationHandler=new MyInvocationHandler(paGamePlayer);
    31         //获取当前线程的类加载器
    32         ClassLoader classLoader=paGamePlayer.getClass().getClassLoader();
    33         //动态生成代理对象(当前线程的类加载器,当前被代理对象的所有接口,生成的代理执行的Handler)
    34         Mlayer mylMlayer=(Mlayer) Proxy.newProxyInstance(paGamePlayer.getClass().getClassLoader(),paGamePlayer.getClass().getInterfaces(), myInvocationHandler);
    35         //执行被代理的方法
    36         String result=mylMlayer.killBoss("王者荣耀之暴君");
    37         System.out.println("AopTest.test02()killBoss执行结果==>"+result);
    38         
    39         String resultSt=mylMlayer.login("王者孙悟空", "12345");
    40         System.out.println("AopTest.test02()login执行结果===>"+resultSt);
    41         
    42         /**
    43          * MyInvocationHandler.invoke()===>动态代理实现了一些增强前..................
    44             SxfGamePlayer.killBoss()要打的怪物名字是===>王者荣耀之暴君
    45             MyInvocationHandler.invoke()===>动态代理实现了一些增强后..................
    46             AopTest.test02()killBoss执行结果==>王者荣耀之暴君这个怪物被打死了
    47             MyInvocationHandler.invoke()===>动态代理实现了一些增强前..................
    48             SxfGamePlayer.login()登陆的名字是===>name=[王者孙悟空]password=[12345]
    49             MyInvocationHandler.invoke()===>动态代理实现了一些增强后..................
    50             AopTest.test02()login执行结果===>sxf你登陆成功了
    51         *
    52          */
    53     }
    54 }
    View Code

    扩展:对生成的代理类进行再次代理

    再次代理的增强

     1 package com.nonbank.commons.aop;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 /**
     6  * 对第一层代理类进行第二次代理
     7  * @author sxf
     8  *
     9  */
    10 public class MyInvocationHandler2 implements InvocationHandler{
    11     
    12     private Object object;
    13     
    14     public MyInvocationHandler2(Object object){
    15         this.object=object;
    16     }
    17 
    18     @Override
    19     public Object invoke(Object proxy, Method method, Object[] args)
    20             throws Throwable {
    21         System.out.println("MyInvocationHandler2.invoke()sxfffffffffffffffffffffffffffffffstart");
    22         Object objectd=method.invoke(this.object,args);
    23         System.out.println("MyInvocationHandler2.enclosing_method()sxffffffffffffffffffffend");
    24         
    25         return objectd;
    26     }
    27 
    28     
    29     
    30 }
    View Code

    再次代理的实现

     1 package com.nonbank.commons.aop;
     2 
     3 import java.lang.reflect.Proxy;
     4 import java.sql.Connection;
     5 import java.sql.DriverManager;
     6 import java.sql.SQLException;
     7 
     8 public class AopTest {
     9 
    10     public static void main(String[] args) {
    11         test02();
    12     }
    13     
    14     /**
    15      * 普通的静态代理
    16      */
    17     public static void test01(){
    18         //被代理角色
    19         GamePlayer gamePlayer=new GamePlayer();
    20         //代理角色
    21         GamePlayer_Poxy poxy=new GamePlayer_Poxy(gamePlayer);
    22         //代理角色持有被代理角色的引用,代理和被代理实现相同的接口
    23         poxy.killBoss();
    24     }
    25     
    26     /**
    27      * 动态代理测试
    28      */
    29     public static void test02(){
    30         //被代理对象的真实角色
    31         SxfGamePlayer paGamePlayer=new SxfGamePlayer();
    32         //生成代理执行的Handler
    33         MyInvocationHandler myInvocationHandler=new MyInvocationHandler(paGamePlayer);
    34         //获取当前线程的类加载器
    35         ClassLoader classLoader=paGamePlayer.getClass().getClassLoader();
    36         //动态生成代理对象(当前线程的类加载器,当前被代理对象的所有接口,生成的代理执行的Handler)
    37         Mlayer mylMlayer=(Mlayer) Proxy.newProxyInstance(paGamePlayer.getClass().getClassLoader(),paGamePlayer.getClass().getInterfaces(), myInvocationHandler);
    38     
    39         MyInvocationHandler2 myInvocationHandler2=new MyInvocationHandler2(mylMlayer);
    40         Mlayer mylMlayer2=(Mlayer) Proxy.newProxyInstance(paGamePlayer.getClass().getClassLoader(),paGamePlayer.getClass().getInterfaces(), myInvocationHandler2);
    41         //执行被代理的方法
    42         String result=mylMlayer2.killBoss("王者荣耀之暴君");
    43         System.out.println("AopTest.test02()killBoss执行结果==>"+result);
    44         
    45         String resultSt=mylMlayer2.login("王者孙悟空", "12345");
    46         System.out.println("AopTest.test02()login执行结果===>"+resultSt);
    47         
    48         /**
    49          * MyInvocationHandler2.invoke()sxfffffffffffffffffffffffffffffffstart
    50             MyInvocationHandler.invoke()===>动态代理实现了一些增强前..................
    51             SxfGamePlayer.killBoss()要打的怪物名字是===>王者荣耀之暴君
    52             MyInvocationHandler.invoke()===>动态代理实现了一些增强后..................
    53             MyInvocationHandler2.enclosing_method()sxffffffffffffffffffffend
    54             AopTest.test02()killBoss执行结果==>王者荣耀之暴君这个怪物被打死了
    55             MyInvocationHandler2.invoke()sxfffffffffffffffffffffffffffffffstart
    56             MyInvocationHandler.invoke()===>动态代理实现了一些增强前..................
    57             SxfGamePlayer.login()登陆的名字是===>name=[王者孙悟空]password=[12345]
    58             MyInvocationHandler.invoke()===>动态代理实现了一些增强后..................
    59             MyInvocationHandler2.enclosing_method()sxffffffffffffffffffffend
    60             AopTest.test02()login执行结果===>sxf你登陆成功了
    61 
    62         *
    63          */
    64     }
    65     
    66     
    67     public static void test03() throws SQLException{
    68         Connection connection= DriverManager.getConnection("连接URL", "用户名", "密码");
    69         //关闭自动提交
    70         connection.setAutoCommit(false);
    71         //该连接所有操作进行提交提交
    72         connection.commit();
    73         //该链接所有操作进行回滚
    74         connection.rollback();
    75         //connection.rollback(savepoint);
    76         //spring的事务管理器,在aop编程(动态代理)的增强方法中实现事务管理的编码,可以实现提交和回滚
    77         
    78     }
    79     
    80     
    81     public static void springInvoker(){
    82         
    83     }
    84 }
    View Code

    三:spring的事务管理,就是基于动态代理aop编程实现事务管理,声明式事务编程,编码式事务编程

     1 public static void test03() throws SQLException{
     2         Connection connection= DriverManager.getConnection("连接URL", "用户名", "密码");
     3         //关闭自动提交
     4         connection.setAutoCommit(false);
     5         //该连接所有操作进行提交提交
     6         connection.commit();
     7         //该链接所有操作进行回滚
     8         connection.rollback();
     9         //connection.rollback(savepoint);
    10         //spring的事务管理器,在aop编程(动态代理)的增强方法中实现事务管理的编码,可以实现提交和回滚
    11         
    12     }
    View Code
  • 相关阅读:
    cookie,sessionStorage,localStorage
    存储方式与传输方式
    为什么css放在顶部而js写在后面
    常见的web安全及防护原理
    web缓存
    http协议理解
    http与https
    get/post的区别
    JZOJ 3571. 【GDKOI2014】内存分配
    JZOJ 3570. 【GDKOI2014】壕壕的寒假作业
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/6393938.html
Copyright © 2011-2022 走看看