美文网首页设计模式
[码歌老薛]动态代理之多级代理实现方案以及细节分析

[码歌老薛]动态代理之多级代理实现方案以及细节分析

作者: 坑王老薛 | 来源:发表于2018-12-19 21:48 被阅读62次

    本内容均属码歌老薛原创,需要转载请注明出处:https://www.jianshu.com/p/29548a7b606f
    对于本文章如果有疑问,请加老薛qq:1811112688

    1-7-6 多级代理

    业务分析

    实现业务场景:虾米吃海藻 小鱼吃虾米,大鱼吃小鱼

    简单业务概述,当虾米吃海草时,小鱼一直在监视虾米有没有执行eat();方法,如果执行则小鱼执行eatSmallShrimp();大鱼执行eatLitteFish();将小鱼吃掉。

    1-7-6 需求分析第一步
    i:主要业务和次要业务的分析,这里吃为主要业务,当虾米吃了海藻,意味着小鱼一直在监听虾米吃的动作,如果虾米吃的动作一旦完成,或者被调用,意味着小鱼就要准备出场,将虾米干掉。
    ii:根据上面的分析也就意味着小鱼应该是一个Agent对象,里面存储了次要业务,吃小虾米。
    
    1-7-7 编写方式

    1: 创建主要业务接口

    2:创建虾米对象且实现主要业务接口

    3:创建实现处理器类

    4:编写代理工厂,代理对象通过工厂创建出来

    5:编写测试类

    1-7-8 测试用例
    主要业务接口
    /**
     * 编写主要核心业务逻辑
     */
    public interface Service {
        void eat();
    }
    
    虾米类实现主要业务接口
    public class SmallShrimp implements Service {
        @Override
        public void eat() {
            System.out.println("虾米吃海藻");
        }
    }
    
    代理工厂
    public class ProxyFactory {
    
        public static Service getInstance(Class<?> clz){
    
            //创建真实角色
            SmallShrimp shrimp = new SmallShrimp();
    
            //获取代理角色 (实现了处理器接口的对象)
            LittleFish fish = new LittleFish(shrimp);
    
            //获取监听对象,查看真实角色是否执行了主要业务
            Class[] clzArrays = {Service.class};
            Service proxy = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,fish);
           
            return proxy;
        }
    }
    
    创建实现处理器类
    public class LittleFish implements InvocationHandler {
    
        //包装真实角色
        private Service realObj;
    
        public LittleFish(Service realObj) {
            this.realObj = realObj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            //监听虾米是否开始吃海藻了
            method.invoke(realObj,args);
    
            //准备让小鱼吃虾米
            eatSS();
            return null;
        }
    
        public void eatSS(){
            System.out.println("小鱼准备吃虾米");
        }
    }
    
    测试类
    public class Test {
        public static void main(String[] args) throws Exception {
            Service service =  ProxyFactory.getInstance(SmallShrimp.class);
    
            service.eat();
    
        }
    }
    
    结论
    虾米吃海藻
    小鱼准备吃虾米
    
    1-7-9 需求分析第二步
    i: 分析大鱼小鱼的业务场景,大鱼在监控小鱼,如果发现小鱼吃了虾米,
    那么此时大鱼开始执行它吃小鱼的功能。这里有一个问题需要我们解决,
    对于小鱼来说,它的主要业务好像应该是吃小鱼的方法eatSS();
    这里要注意:
    ii:因为整个业务场景中,其实是虾米吃海藻发生之后,
    代理角色才被创建以及开始执行的。
    
    1-7-7 编写方式

    1:创建实现处理器类 代理实现类,大鱼类

    4:编写代理工厂,代理对象通过工厂创建出来

    5:编写测试类

    1-7-8 编写方式
    主要业务接口
    /**
     * 编写主要核心业务逻辑
     */
    public interface Service {
        void eat();
    }
    
    虾米类实现主要业务接口
    public class SmallShrimp implements Service {
        @Override
        public void eat() {
            System.out.println("虾米吃海藻");
        }
    }
    
    代理工厂
    public class ProxyFactory {
    
        public static Service getInstance(Class<?> clz){
    
            //创建真实角色
            Service shrimp = new SmallShrimp();
    
            //获取代理角色 (实现了处理器接口的对象)
            InvocationHandler fish = new LittleFish(shrimp);
    
            //获取监听对象,查看真实角色是否执行了主要业务
            Class[] clzArrays = {Service.class};
            Service proxy1 = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,fish);
    
            //创建代理实现类对象
            InvocationHandler bigFish = new BigFish(proxy1);
            //这里获取监听对象 查看小鱼是否执行了吃虾米的操作,但是整个业务流程其实都是起始于小鱼除了虾米 所以这里负责
            //查看的依旧是小鱼
            Service proxy2 = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,bigFish);
    
            return proxy2;
        }
    }
    
    
    创建实现处理器类1
    public class LittleFish implements InvocationHandler {
    
        //包装真实角色
        private Service realObj;
    
        public LittleFish(Service realObj) {
            this.realObj = realObj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            //监听虾米是否开始吃海藻了
            method.invoke(realObj,args);
    
            //准备让小鱼吃虾米
            eatSS();
            return null;
        }
    
        public void eatSS(){
            System.out.println("小鱼准备吃虾米");
        }
    }
    
    创建实现处理器类2
    public class BigFish implements InvocationHandler {
    
        private Service proxy;
    
        public BigFish(Service proxy) {
            this.proxy = proxy;
        }
    
        @Override
        public Object invoke(Object listener, Method method, Object[] args) throws Throwable {
            /**
             * 监听小鱼有没有吃虾米 如果吃了则准备吃小鱼 这里的问题是真实的执行对象是谁?
             * 按照我们思路应该是小鱼,但是小鱼执行的是invoke方法,而该方法其实是通过监控执行的,而不是
             * 主动调用的,这个方法的调用是由产生的代理对象执行的,所以这里我们执行该方法的对象应该是Proxy,
             * 所以对于BigFish而言需要一个Proxy的引用
             */
            method.invoke(proxy,args);
            eatLF();
            return null;
        }
        //辅助业务
        public void eatLF(){
            System.out.println("大鱼吃小鱼");
        }
    }
    
    
    测试类
    public class Test {
        public static void main(String[] args) throws Exception {
            Service service =  ProxyFactory.getInstance(SmallShrimp.class);
    
            service.eat();
    
        }
    }
    
    结论
    虾米吃海藻
    小鱼准备吃虾米
    大鱼吃小鱼
    

    相关文章

      网友评论

        本文标题:[码歌老薛]动态代理之多级代理实现方案以及细节分析

        本文链接:https://www.haomeiwen.com/subject/qgvskqtx.html