zoukankan      html  css  js  c++  java
  • Spring AOP:Java动态代理和CGlib

    JDK动态代理设计模式

    核心类:InvocationHandlerProxy。只能代理接口。

    Java动态代理核心代码

    /**
     * Java动态代理
     *
     * @Author YangXuyue
     * @Date 2018/09/17 23:46
     */
    public class MyInvocationHandler implements InvocationHandler {
    
        /**
         * 执行方法的对象实例
         */
        private Object target;
    
        public MyInvocationHandler(Object target) {
            this.target = target;
        }
        
        // proxy是最终生成的代理类,一般不会用到
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            long start = System.currentTimeMillis();
    
            Object object = method.invoke(target, args);
    
            System.out.println("方法:" + method.getName() + "执行了:" + (System.currentTimeMillis() - start) + " ms");
    
            return object;
        }
    
        // 获取代理实例
        public static Object proxy(Object target) {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(), new MyInvocationHandler(target));
        }
    }

    测试

            Waiter waiter = new NaiveWaiter();
            Waiter proxy = (Waiter) MyInvocationHandler.proxy(waiter);
            // 在执行以下方法的时候,这些方法都已经被增强了!
            proxy.sayHello("yangxuyue");
            proxy.sayBye("yangxuyue");

    在动态代理的invoke方法里边,在原有方法的调用前后“织入”了我们的代码。其实这就是AOP中横切的过程,代理对象中在方法调用前后“植入”自己写的通用代码其实就是AOP中织入的过程!这个织入的代码也就是横切逻辑,织入代码的过程其实就是在原有的方法前后增强原方法的过程!这种技术手段就是AOP

    CGLib

    CGLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势的织入横切逻辑。

    pom.xml

            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.8</version>
            </dependency>

    核心类

    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class CglibProxy implements MethodInterceptor {
        private Enhancer enhancer = new Enhancer();
    
        public Object getProxy(Class clazz) {
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        // object:目标类的实例 method:目标类方法的反射对象 args:方法的动态参数 proxy:代理类实例
        // intercept(Object, Method, Object[], MethodProxy) 拦截所有目标类的调用
        @Override
        public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            long start = System.currentTimeMillis();
    
            Object result = proxy.invokeSuper(object, args);
    
            System.out.println(result);
    
            System.out.println("方法:" + method.getName() + "执行了:" + (System.currentTimeMillis() - start) + " ms");
    
            return object;
        }
    }

    测试

            CglibProxy proxy = new CglibProxy();
            VoiceBean bean = (VoiceBean) proxy.getProxy(VoiceBean.class);
            bean.saySomething();

    代理类的类名字

     VoiceBean$$EnhancerByCGLIB$$a8907e36
  • 相关阅读:
    windows中dos命令指南
    HDU 2084 数塔 (dp)
    HDU 1176 免费馅饼 (dp)
    HDU 1004 Let the Balloon Rise (map)
    变态杀人狂 (数学)
    HDU 2717 Catch That Cow (深搜)
    HDU 1234 开门人和关门人 (模拟)
    HDU 1070 Milk (模拟)
    HDU 1175 连连看 (深搜+剪枝)
    HDU 1159 Common Subsequence (dp)
  • 原文地址:https://www.cnblogs.com/yang21/p/9970199.html
Copyright © 2011-2022 走看看