zoukankan      html  css  js  c++  java
  • cglib 多重 代理示例-2

    from:  http://thinkinjava.cn/2018/10/%E4%BD%BF%E7%94%A8-Cglib-%E5%AE%9E%E7%8E%B0%E5%A4%9A%E9%87%8D%E4%BB%A3%E7%90%86/ ,  https://blog.csdn.net/ahilll/article/details/82943836

    /*
    简单实现 Cglib 多重代理
    先说一下思路:事实上很简单,只需要再拦截器里放一个过滤器链即可,用户在过滤器里拦截多重调用。
    这些拦截器,就像你加 @Around 注解的方法,只不过我们这里没有 Spring 那么方便而已。
    */
    public class Test {
        public static void main(String[] args) {
            Object proxy = ProxyFactory.create().getProxy(new SayHello());
            proxy.toString();
        }
    
        static class SayHello {
            @Override
            public String toString() {
                return "hello cglib !";
            }
        }
    }

    核心代理工厂:

    public class ProxyFactory {
        private ProxyFactory() {}
        public static ProxyFactory create() {
            return new ProxyFactory();
        }
        public Object getProxy(Object origin) {
            final Enhancer en = new Enhancer();
            en.setSuperclass(origin.getClass());
            List<Chain.PointInterface> list = new ArrayList<>();
            list.add(new PointInterface1());
            list.add(new PointInterface2());
            System.out.println("---12->进入了 获取代理对象的方法: getProxy(Object origin)");
            en.setCallback(new SpringCglibProxyInterceptor(new Chain(list, origin)));
            return en.create();
        }
        private class SpringCglibProxyInterceptor implements MethodInterceptor {//在这个拦截器里放一个过滤器链 SpringCglibProxy
            Chain chain;
            public SpringCglibProxyInterceptor(Chain chain) {
                System.out.println("---13->进入了 SpringCglibProxyInterceptor的构造方法");
                this.chain = chain;
            }
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
                    throws Throwable {
                System.out.println("---14->进入了 SpringCglibProxyInterceptor.class中 基层CglibPoxy接口的实现方法");
                return chain.proceed2(); //引入 滤器链
            }
    
        }
    }
    public class Chain {
        private List<PointInterface> list;
        private int index = -1;
        private Object target;
    
        public Chain(List<PointInterface> list, Object target) {
            System.out.println("---12.1->进入了 SpringCglibProxyInterceptor构造方法中的对象参数Chain的构造方法");
            this.list = list;
            this.target = target;
        }
    
        //滤器链
        public Object proceed2() throws InterruptedException {
            System.out.println("---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法");
            Object result;
            if (++index == list.size()) {   // 这是干正事
                result = (target.toString());
                System.err.println("---50->干正事-ing-(proceed2()方法中)Target Method invoke result : " + result);
                System.err.println("---51->总结:1.切面一次性处理<正事>之前的琐事-->2.干正事-->3.切面一次性处理<正事>之后的琐事 ");
            } else {                        // 这是干正事之前 做的事情
                System.err.println("---49->干正事-before-(proceed2()方法中)做的事情--X: "+(index) + "--start");
                PointInterface pointInterface = list.get(index);
                result = pointInterface.proceed3(this);
                System.err.println("---49->干正事-before-(proceed2()方法中)做的事情--X: "+(index) + "--end");
            }
            return result;
        }
        interface PointInterface {
            Object proceed3(Chain chain) throws InterruptedException;
        }
    }
    public class PointInterface1 implements Chain.PointInterface {
        @Override
        public Object proceed3(Chain chain) throws InterruptedException {
            System.out.println("point 1 before");
            Thread.sleep(20);
            Object result = chain.proceed2();
            Thread.sleep(20);
            System.out.println("point 1 after");
            return result;
        }
    }
    public class PointInterface2 implements Chain.PointInterface {
        @Override
        public Object proceed3(Chain chain) throws InterruptedException {
            System.out.println("point 2 before");
            Thread.sleep(20);
            Object result = chain.proceed2();
            Thread.sleep(20);
            System.out.println("point 2 after");
            return result;
        }
    }

    结果:

    ---12->进入了 获取代理对象的方法: getProxy(Object origin)
    ---12.1->进入了 SpringCglibProxyInterceptor构造方法中的对象参数Chain的构造方法
    ---13->进入了 SpringCglibProxyInterceptor的构造方法
    ---14->进入了 SpringCglibProxyInterceptor.class中 基层CglibPoxy接口的实现方法
    ---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
    point 1 before
    ---49->干正事-before-(proceed2()方法中)做的事情--X: 0--start
    ---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
    point 2 before
    ---49->干正事-before-(proceed2()方法中)做的事情--X: 1--start
    ---50->干正事-ing-(proceed2()方法中)Target Method invoke result : hello cglib !
    ---51->总结:1.切面一次性处理<正事>之前的琐事-->2.干正事-->3.切面一次性处理<正事>之后的琐事 
    ---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
    point 2 after
    ---49->干正事-before-(proceed2()方法中)做的事情--X: 2--end
    point 1 after
    ---49->干正事-before-(proceed2()方法中)做的事情--X: 2--end
  • 相关阅读:
    leetcode 15. 三数之和
    leetcode 168. Excel表列名称
    142. 环形链表 II
    144. 二叉树的前序遍历(非递归)
    415. 字符串相加
    剑指 Offer 31. 栈的压入、弹出序列
    剑指 Offer 27. 二叉树的镜像
    剑指 Offer 29. 顺时针打印矩阵
    剑指 Offer 10- II. 青蛙跳台阶问题
    VBA 实现excel单元格多选
  • 原文地址:https://www.cnblogs.com/hahajava/p/9811872.html
Copyright © 2011-2022 走看看