java设计模式之动态代理模式

╰半橙微兮° 2023-07-15 06:00 48阅读 0赞

一、解释说明(jdk动态代理)

动态代理就是在静态代理的基础上,把代理类动态生成了。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE4MzI5MjU_size_16_color_FFFFFF_t_70

二、案例代码

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE4MzI5MjU_size_16_color_FFFFFF_t_70 1

1、抽象角色代码案例如下

  1. package 设计模式.动态代理;
  2. //明星(抽象角色)
  3. public interface Star {
  4. //唱歌
  5. public void sing() throws Throwable;
  6. }

2、真实角色代码案例如下

  1. package 设计模式.动态代理;
  2. //周杰伦(真实角色)
  3. public class SuperStar implements Star{
  4. @Override
  5. public void sing() {
  6. System.out.println("周杰伦在唱歌");
  7. }
  8. }

3、角色处理器代码如下

  1. package 设计模式.动态代理;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. //明星处理器(总管大人)
  5. public class StarHandler implements InvocationHandler {
  6. private Star star;
  7. //把被代理的对象注入进来
  8. public StarHandler(Star star){
  9. this.star = star;
  10. }
  11. //总控方法,所有方法的拦截器
  12. @Override
  13. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  14. System.out.println("调用前加的事件");
  15. method.invoke(star,args);
  16. System.out.println("调用后加的事件");
  17. return null;
  18. }
  19. }

4、客户端代码如下

  1. package 设计模式.动态代理;
  2. import java.lang.reflect.Proxy;
  3. //客户端
  4. public class Client {
  5. public static void main(String[] args) throws Throwable {
  6. //创建真实角色
  7. Star star = new SuperStar();
  8. //把真实角色注册到处理器中
  9. StarHandler starHandler = new StarHandler(star);
  10. //动态生成代理对象,代理对象的所有方法都会调用starHandler的invoke方法,以此达到拦截效果
  11. Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, starHandler);
  12. //调用方法
  13. proxy.sing();
  14. }
  15. }

原理说明:

模拟动态生成的代理类大概代码如下

  1. package 设计模式.动态代理;
  2. import java.lang.reflect.Method;
  3. //模拟动态生成的代理类
  4. public class StarProxy implements Star{
  5. private StarHandler starHandler;
  6. //把处理器注册进来
  7. public StarProxy(StarHandler starHandler){
  8. this.starHandler = starHandler;
  9. }
  10. //所有的方法都转为调用处理器的方法
  11. @Override
  12. public void sing() throws Throwable {
  13. starHandler.invoke(this, Star.class.getMethods()[0],null);
  14. }
  15. }

客户端调用代码如下

  1. package 设计模式.动态代理;
  2. //模拟的客户端
  3. public class ClientOne {
  4. public static void main(String[] args) throws Throwable {
  5. //创建真实对象
  6. Star star = new SuperStar();
  7. //把真实对象注册到处理器中
  8. StarHandler starHandler = new StarHandler(star);
  9. //把处理器注册到代理对象中
  10. StarProxy starProxy = new StarProxy(starHandler);
  11. //调用方法
  12. starProxy.sing();
  13. }
  14. }

三、适用场景

1、struts2中拦截器的实现

2、数据库连接池关闭处理

3、Hibernate延迟加载的实现

4、mybatis中实现拦截器插件

5、AspectJ的实现

6、spring中AOP的实现(日志拦截,声明式事务处理)

7、web service

8、RMI远程调用

四、优缺点

与静态代理类似,只不过代码耦合度降低了。

发表评论

表情:
评论列表 (有 0 条评论,48人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java设计模式动态代理

    动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问。 我们首先来谈谈什么是代理模式。假设客户带着需求去找公司,显然不会直接和软件工程师谈,

    相关 java设计模式动态代理

    前言 为了更好的理解代理模式,首先根据生活中实际场景进行模拟,让我们在生活中去体验设计思想的美妙。 场景描述 “病从口入”这句成语告诉我们注意饮食健康,小六同学想