• 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
  • 相关阅读:
    ubuntu 10.04安装增强功能 共享文件夹
    CRF简介入门
    Ant 的build.xml 详解
    eclipse中各种颜色和背景的设置
    第13章 类继承 --抽象基类
    第13章 类继承
    团队开发之绩效考核二
    站立会议
    团队站立会议
    团队开发站立会议
  • 原文地址:https://www.cnblogs.com/yang21/p/9970199.html
Copyright © 2020-2023  润新知