程序設計優化——(2)代理模式之動態代理

  簡介:動態代理是指在運行時,動態生成代理類。即代理類的字節碼將在運行時生成並載入當前的ClassLoader。與靜態代理類相比,有諸多好處。不須要爲真實主題寫一個形式上徹底同樣的封裝類,若接口過多,則會代理接口也不少,接口稍微改動,代理接口也要進行變動;其次,使用動態代理能夠在運行時指定代理類的執行邏輯,從而提高系統的靈活性。java

  動態代理有JDK自帶的動態代理,CGLIB、Javassist或者ASM庫。JDK的動態代理簡單,內置在JDK中,所以不須要引入第三方jar包,但功能較弱。CGLIB和Javassist都是高級字節碼生成庫,整體性能比JDK自帶的好,功能強大。這裏主要介紹CGLIB的使用maven

 

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

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

 

 2.主題接口spa

    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接口)code

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,完成代理類和主題接口的工做xml

  建立代理對象的步驟:對象

  1) 指定切入器,定義代理類的邏輯blog

  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代理模式的應用:一是屬性的延遲加載;二是關聯表的延遲加載。

相關文章
相關標籤/搜索