CGLIB動態代理

CGLIB動態代理

cglib是什麼?

CGLIB(Code Generation Library)是一個開源項目!java

是一個強大的,高性能,高質量的Code生成類庫,它能夠在運行期擴展Java類與實現Java接口。spring

CGLIB是一個強大的高性能的代碼生成包。它普遍的被許多AOP的框架使用,例如Spring AOP和dynaop,爲他們提供方法的interception(攔截)。最流行的OR Mapping工具hibernate也使用CGLIB來代理單端single-ended(多對一和一對一)關聯(對集合的延遲抓取,是採用其餘機制實現的)。EasyMock和jMock是經過使用模仿(mock)對象來測試java代碼的包。它們都經過使用CGLIB來爲那些沒有接口的類建立模仿(mock)對象。app

CGLIIB實現動態代理

先來個service 注意沒有接口框架

public class CglibService {
    public CglibService() {
        System.out.println("CglibDao 構造方法");
    }

    /** * 該方法不能被子類覆蓋,Cglib是沒法代理final修飾的方法的 * @param name * @return */
    final public String sayOthers(String name){
        System.out.println("CglibDao final sayOthers:"+name);
        return null;
    }

    public void sayHello(){
        System.out.println("CglibDao:sayHello");
    }
}
複製代碼

新建一個Interceptor實現org.springframework.cglib.proxy.MethodInterceptoride

public class MyMethodInterceptor implements MethodInterceptor {
    /** * * @param o 代理對象 * @param method 被代理的對象方法 * @param objects 方法入參 * @param methodProxy 代理方法 * @return * @throws Throwable */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("======插入後置通知======");
        return object;
    }
}

複製代碼

新建測試類工具

/** * cglib 動態代理測試 */
public class cglibAgentTest {

    @Test
    public void testCglibAgent(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibService.class);
        // 設置enhancer的回調對象
        enhancer.setCallback(new MyMethodInterceptor());
        // 建立代理對象
        CglibService proxy= (CglibService)enhancer.create();
        // 經過代理對象調用目標方法
        proxy.sayHello();
        proxy.sayOthers("小明");
    }
}
複製代碼

打印的值性能

CglibDao 構造方法
======插入前置通知======
CglibDao:sayHello
======插入後置通知======
CglibDao final sayOthers:小明
複製代碼

能夠看出來 會先執行他的構造方法 當調用sayHello時候會先調用他們的代理方法 若是當方法爲final修飾時 沒法實現代理測試

總結

Cglib與InvocationHandler實現的動態代理不一樣是 cglib不用寫接口spa

Spring中的aop也能夠經過配置採用Cglib方式hibernate

除了CGLIB包,腳本語言例如Groovy和BeanShell,也是使用ASM來生成java的字節碼。固然不鼓勵直接使用ASM,

由於它要求你必須對JVM內部結構包括class文件的格式和指令集都很熟悉,因此推薦用Cglib

5d0501353921378647
相關文章
相關標籤/搜索