zoukankan      html  css  js  c++  java
  • 代理模式及实现

     

    代理对象和委托对象继承相同接口,并控制外部对委托对象的访问。

    1. 静态代理: 代理类在编译期确定,需要针对为每个接口实现不同的代理。

    接口(Human):

    public interface Human{
        public void eatFood();
    }

    委托类(HumanImpl):

    public class HumanImpl implements Human{
        public void eatFood(){
            System.out.print("真香!");
        }
    }

    代理类(HumanProxy):

    public class HumanProxy implements Human{
        private Human human;
    
        public HumanProxy(Human human){
                this.human = human;
        }
        
        public void eatFood(){
            before();
            human.eatFood();
            after();
        }
    }

    2. JDK动态代理: 运行期生成代理类

      在代理类和委托类之间生成中介类,该类实现 InvocationHandler 接口。对委托对象方法的调用会转到中介对象的invoke()方法中,method标识了调用哪一个方法(通过反射获取),args代表方法参数。

    public class HumanDynamicProxy implements InvocationHandler{
        //委托对象
        private Human human;
        public HumanDynamicProxy(Human human){
            this.human = human;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            // 使用反射
            Object result = method.invoke(human, args);
            after();
            return result;
        }
    }

    测试代码:

    public static void main(String[] args){
        //委托对象
        Human realHuman = new HumanImpl();
        //中介
        InvocationHandler  handler = new HumanDynamicProxy(human);
        //动态代理,需要指定要的实现的接口,使用反射通过接口获取方法名,拼接出类的字符串再构造出代理类
        Human proxy = (Human) Proxy.newProxyInstance(realHuman.getClass().getClassLoader(), realhuman.getClass().getInterfaces(), handler);
        //通过代理类,执行方法;
        proxy.eatFood();

    3. CGLIB动态代理(委托类不需要实现某接口)

    public class Man{
        public void eatFood(){
            System.out.print("真香");
        }
    }

      生成一个类似的中介类,实现MethodInterceptor接口,方法调用转发到该类的intercept()方法。

    class ManMethodInterceptor implements MethodInterceptor{
      private Man man;
      public ManMethodInterceptor(Man man){
        this.man = man;
      }
       @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable{ before(); Object result = method.invoke(man, args); after(); return result; }

      测试代码:

    Enhancer enhancer = new Enhancer();
    //指定委托目标
    enhancer.setSuperclass(Man.class);
    //指定中介类
    enhancer.setCallback(new ManMethodInterceptor());
    //生成代理类
    Man man = (Man) enhancer.create();
    hello.eatFood();

    参考:https://blog.csdn.net/a396901990/article/details/26015977

    人生就像蒲公英,看似自由,其实身不由己。
  • 相关阅读:
    [算法分析]计数排序
    [置顶] 基于stm32f103zet6之UC/OS_II的学习1(初步移植OS点灯大法)
    IOS开发(59)之Block Object的调用
    【译】测试员,敢问路在何方?来自微软工程师
    各种字符串hash
    hdu 2579 BFS
    qq相册
    程序人生之我们的故事:十年如歌(9)
    关联模型和无限极分类
    十大技巧破解电话面试
  • 原文地址:https://www.cnblogs.com/walker993/p/9439619.html
Copyright © 2011-2022 走看看