• 动态代理


    常用的动态代理技术有两种:

    1、JDK代理

    2、Cglib代理

    JDK代理

    要求被代理对象必须有接口,动态代理生成的实际为接口的子类,所以在接收动态代理类是要用父接口。

    public class JdkProxyFactory implements InvocationHandler {
        private Object target;
    
        public JdkProxyFactory(Object target){
            this.target = target;
        }
    
        public Object getProxyObject(){
            //实现第三个参数的invoke方法
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    this);
        }
    //被代理对象方法执行时调用
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("方法执行前增强");
            Object object = method.invoke(target, args);
            System.out.println("方法执行后增强");
    
            if(object == null ){
                object = "";
            }
            System.out.println("将null值变为空串");
    
            return object; //返回方法的返回值
        }
    }

    Cglib代理

    第三方代理框架,已经整合进spring-core包下,被代理对象无需实现接口,代理生成的类为被代理对象的子类。

    public class CglibProxyFactory implements MethodInterceptor {
        private Object target;
        public CglibProxyFactory(Object target){
            this.target = target;
        }
    
        public Object getProxyObject(){
            //实例化cglib增强器
            Enhancer enhancer = new Enhancer();
    
            //设置两个属性
            //1、要代理的类型
            enhancer.setSuperclass(target.getClass());
            //2、设置回调方法
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        /**
         * 被代理对象方法执行时调用
         * @param proxy  生成的代理对象
         * @param method  执行的目标对象的方法
         * @param args  方法参数
         * @param methodProxy  代理后的方法
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("记录日志了。。");
    //        return method.invoke(target, args);
    //        return methodProxy.invoke(target, args);
    //        return methodProxy.invokeSuper(proxy, args);
    //        Object o = method.invoke(target, args);
    //        Object o = methodProxy.invoke(target, args);
            Object o = methodProxy.invokeSuper(proxy, args);
    
            System.out.println(methodProxy.getSignature());
            System.out.println(Arrays.toString(methodProxy.getSignature().getArgumentTypes()));
            System.out.println(methodProxy.getSignature().getName());
            System.out.println(methodProxy.getSignature().getReturnType());
            System.out.println(methodProxy.getSignature().getDescriptor());
            System.out.println(methodProxy.getSuperName());
            System.out.println("记录日志结束。。。");
    
            return o;
        }
    }
  • 相关阅读:
    PowerShell_零基础自学课程_7_Powershell中重定向机制、目录和文件管理
    volcanol_C语言学习趣事汇总贴
    linux_shell_2_shell 中的变量特性
    PowerShell_零基础自学课程_5_自定义PowerShell环境及Powershell中的基本概念
    volcanol_Linux_问题汇总系列_2_如何在linux和windows主机之间共享文件
    C语言学习趣事_你不知道的C语言应用
    volcanol_Windows_Powershell_汇总贴
    PowerShell_零基础自学课程_4_PowerShell的别名功能、错误管理功能和系统资源区域导航
    Sqlite 管理工具 SQLiteDeveloper及破解
    android建立Menu详解
  • 原文地址:https://www.cnblogs.com/liuyiyuan/p/13089069.html
Copyright © 2020-2023  润新知