zoukankan      html  css  js  c++  java
  • 程序设计优化——(2)代理模式之动态代理

      简介:动态代理是指在运行时,动态生成代理类。即代理类的字节码将在运行时生成并载入当前的ClassLoader。与静态代理类相比,有诸多好处。不需要为真实主题写一个形式上完全一样的封装类,若接口过多,则会代理接口也很多,接口稍微改动,代理接口也要进行变更;其次,使用动态代理可以在运行时指定代理类的执行逻辑,从而提升系统的灵活性。

      动态代理有JDK自带的动态代理,CGLIB、Javassist或者ASM库。JDK的动态代理简单,内置在JDK中,因此不需要引入第三方jar包,但功能较弱。CGLIB和Javassist都是高级字节码生成库,总体性能比JDK自带的好,功能强大。这里主要介绍CGLIB的使用

    1.在maven工程的pom.xml中引入cglib的配置

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

     2.主题接口

        package com.hxc.proxy.proxyMode;
        
        /**
         * <p>Description: 主题接口</p>
         * @author Huang Xiaocong
         * @data 2019年10月27日
         */
        public interface IDBQuery {
            String request();
        }

    3.真实主题

        package com.hxc.proxy.proxyMode;
        /**
         * <p>Description: 真实主题</p>
         * @author Huang Xiaocong
         * @data 2019年10月27日
         */
        public class DBQuery implements IDBQuery {
        
            public DBQuery() {
                try {
                    Thread.sleep(1000);    //模拟执行过程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            public String request() {
                return "request String";
            }
        
        }

    4.代理类 CGLIB代理类实现MethodInterceptor接口(JDK自带的动态代理实现InvocationHandler接口)

    package com.hxc.proxy.proxyMode;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    /**
     * <p>Description: 代理类</p>
     * @author Huang Xiaocong
     * @data 2019年10月30日
     */
    public class CglibDbQueryInterceptor implements MethodInterceptor {
    
        private IDBQuery real = null;
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            if(real == null) {
                real = new DBQuery();
            }
            return real;
        }
    
    }

    5.Main,完成代理类和主题接口的工作

      创建代理对象的步骤:

      1) 指定切入器,定义代理类的逻辑

      2)指定实现的接口

      3)生成代理类的实例

        package com.hxc.proxy.proxyMode;
    import net.sf.cglib.proxy.Enhancer;
    
    /**
         * <p>Description: 客户端</p>
         * @author Huang Xiaocong
         * @data 2019年10月27日
         */
        public class Main {
            
            public static void main(String[] args) {
                IDBQuery dbQuery = createCglibProxy();
                String request = dbQuery.request();
                System.out.println(request);
            }
            
            public static IDBQuery createCglibProxy() {
                Enhancer enhance = new Enhancer();
                enhance.setCallback(new CglibDbQueryInterceptor());     //指定切入器,定义代理类逻辑
                //指定实现的接口
                enhance.setInterfaces(new Class[] {IDBQuery.class});
                //生成代理类的实例
                IDBQuery object = (IDBQuery) enhance.create();
                return object;
            }
        
        }

      对动态代理最经典的用例就是Hibernate代理模式的应用:一是属性的延迟加载;二是关联表的延迟加载。

  • 相关阅读:
    模型定义
    聚合、原生和子查询
    PHP curl扩展
    时间查询
    查询表达式
    HTTP协议的Keep-Alive 模式
    抽象类可以没有抽象方法
    Nginx解决前端跨域问题,Nginx反向代理跨域原理
    Nginx配置文件不生效,Nginx配置文件重启也不生效
    php openssl加密解密函数
  • 原文地址:https://www.cnblogs.com/sun-flower1314/p/11748056.html
Copyright © 2011-2022 走看看