程序设计优化——(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代理模式的应用:一是属性的延迟加载;二是关联表的延迟加载。

原文地址:https://www.cnblogs.com/sun-flower1314/p/11748056.html