java代理模式之动态代理

先来总结分析下代理模式。

动态代理需要的元素:

1.本身的逻辑接口;

2.代理逻辑部分(实现InvocationHandler接口);

客户端:

1.创建本地逻辑的接口的实例。

2.创建InvocationHandler接口的实例。

3.调用java.lang.reflect.Proxy#newProxyInstance生成代理类。

4.调用代理类相应的方法运行。

动态:代理类对应的class类在运行期生成。

限制:本地逻辑必须面向接口。

代码:

抽象接口的类图如下:

      --图来自设计模式之禅

所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类。其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理。

代码实现如下

抽象主题类或者接口:

复制代码

 1 package com.yemaozi.proxy.dynamic;
 2 
 3 /*
 4  * 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理。
 5  */
 6 public interface IGamePlayer {
 7     //登录游戏
 8     public void login(String username, String password);
 9     
10     //击杀Boss
11     public void killBoss();
12     
13     //升级
14     public void upGrade();
15 }

复制代码

 

需要被代理类:

复制代码

 1 package com.yemaozi.proxy.dynamic;
 2 
 3 public class GamePlayer implements IGamePlayer {
 4     
 5     private String name = "";
 6     
 7     public GamePlayer(String name){
 8         this.name = name;
 9     }
10     
11     public void login(String username, String password) {
12         System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");
13     }
14         
15     public void killBoss() {
16         System.out.println(this.name + " 击杀了Boss!");
17     }
18 
19     public void upGrade() {
20         System.out.println(this.name + "升级了!");
21     }
22 
23 }

复制代码

 

动态代理处理器类:

复制代码

 1 package com.yemaozi.proxy.dynamic;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class GamePlayerInvocationHandler implements InvocationHandler{
 7 
 8     //被代理的对象
 9     private Object obj;
10     
11     //将需要代理的实例通过处理器类的构造方法传递给代理。
12     public GamePlayerInvocationHandler(Object obj){
13         this.obj = obj;
14     }
15     
16     public Object invoke(Object proxy, Method method, Object[] args)
17             throws Throwable {
18         Object result = null;
19         if("login".equalsIgnoreCase(method.getName())){
20             //这个在主题方法不受任何影响的情况下,在主题方法前后添加新的功能,或者增强主题方法,
21             //从侧面切入从而达到扩展的效果的编程,就是面向切面编程(AOP Aspect Oriented Programming)。
22             //AOP并不是新技术,而是相对于面向对象编程的一种新的编程思想。在日志,事务,权限等方面使用较多。
23             System.out.println("代理登录游戏!");
24             result = method.invoke(this.obj, args);
25             return result;
26         }
27         result = method.invoke(this.obj, args);
28         return result;
29     }
30 
31 }

复制代码

由于代理是动态产生的,所以不需要再声明代理类。

 

动态代理场景类:

复制代码

package com.yemaozi.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        IGamePlayer gp = new GamePlayer("张三");
        InvocationHandler gpHandler = new GamePlayerInvocationHandler(gp);
        //获取真实主题类的ClassLoader
        ClassLoader classLoader = gp.getClass().getClassLoader();
        //动态产生一个代理者。
        Class<?>[] cls = new Class[]{IGamePlayer.class};
        IGamePlayer proxyGp = (IGamePlayer) Proxy.newProxyInstance(classLoader, cls, gpHandler);
        proxyGp.login("zhangsan", "123456");
        proxyGp.killBoss();
        proxyGp.upGrade();
    }
}

执行结果:
代理登录游戏!
登录名为 zhangsan 进入游戏,张三 登录成功!
张三 击杀了Boss!
张三升级了!

//在此,我们没有创建代理类,但是确实有代理类帮我们完成事情。

复制代码

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值