zoukankan      html  css  js  c++  java
  • 设计模式--动态代理

    本博客借鉴https://www.cnblogs.com/baizhanshi/p/6611164.html

    静态代理

    优点

    代理是客户端不需要知道实现类是什么,怎么做,而客户端只需要知道代理即可(解耦合)

    缺点

    1)代理类和目标类实现了相同的接口,代理类通过目标类实现了相同的方法。这样就会出现大量的代码重复,比如目标列增加一个方法,代理类就也要增加相应的方法

    2)代理类只是为一个目标类服务,如果需要为多个目标类服务就不适应了

    改用办法采用动态代理

     1 package com.study.proxy;
     2 
     3 /**
     4  * 目标接口
     5  * @author xiaojuan
     6  *
     7  */
     8 public interface IDBQuery {
     9     //查询用户
    10     public String getUser();
    11     //查询账户
    12     public String getAccout();
    13     //查询金额
    14     public String getTxn();
    15 }
    目标接口
     1 package com.study.proxy;
     2 
     3 /**
     4  * 目标实现类
     5  * @author xiaojuan
     6  *
     7  */
     8 public class DBQueryImpl implements IDBQuery{
     9 
    10     @Override
    11     public String getUser() {
    12         return "zhangsan";
    13     }
    14 
    15     @Override
    16     public String getAccout() {
    17         // TODO Auto-generated method stub
    18         return "4646446464";
    19     }
    20 
    21     @Override
    22     public String getTxn() {
    23         // TODO Auto-generated method stub
    24         return "45.21";
    25     }
    26     
    27     
    28     
    29 
    30 }
    目标实现类
     1 package com.study.proxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.lang.reflect.Proxy;
     6 
     7 public class DBQueryDynamicProxy implements InvocationHandler{
     8 
     9     //目标对象
    10     private Object target;
    11     
    12     //关联的这个实现类的方法被调用时将被执行时,执行invoke方法
    13     //InvocationHandler接口的方法,proxy表示代理,method表示原对象被调用的方法,args表示方法的参数
    14     //
    15     @Override
    16     public Object invoke(Object proxy, Method method, Object[] args)
    17             throws Throwable {
    18         System.out.println("开始查询数据库:》》》》");
    19         //调用目标方法
    20         Object ret = method.invoke(target, args);
    21         return ret;
    22     }
    23     
    24     //获取代理对象
    25     public Object createProxy(Object target) {
    26         //指定目标对象
    27         this.target = target;
    28         //该方法用于指定类加载器、一组接口及调用处理器生成动态代理类实例
    29         //第一个参数产生代理对象的类加载器,需要将指定为目标对象同一个类加载器
    30         //第二个参数要实现和目标对象一样的接口,所以只需要拿到目标对象的接口
    31         //第三个参数表明这些被拦截的方法在被拦截时需要执行哪个InvocationHandler的invoke方法
    32         Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    33         return proxy;
    34     }
    35 
    36 }
    动态代理类
     1 package com.study.proxy;
     2 
     3 public class Test {
     4 
     5     public static void main(String[] args) {
     6         DBQueryDynamicProxy proxy = new DBQueryDynamicProxy();
     7         IDBQuery query = (IDBQuery) proxy.createProxy(new DBQueryImpl());
     8         System.out.println(query.getUser());
     9         System.out.println(query.getAccout());
    10 
    11     }
    12 
    13 }
    测试类
  • 相关阅读:
    「Codeforces 724F」Uniformly Branched Trees
    「笔记」组合入门题选做
    「算法笔记」组合入门与应用
    「算法笔记」可持久化线段树
    「算法笔记」期望 DP 入门
    「NOIP 2016」换教室
    「算法笔记」基础数论
    「笔记」关于乱搞
    python 的列表遍历删除
    Python基础第三篇:函数
  • 原文地址:https://www.cnblogs.com/zk753159/p/9610701.html
Copyright © 2011-2022 走看看