茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729835 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
FDbench_HD_500G_30G_C.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

爪哇咖啡屋 : [轉貼]CGLIB(Code Generation Library)詳解

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15773
[轉貼]略談 cglib

略談 cglib

Java 本身的動態代理,必須要基於介面定義,若類別並沒有實作特定介面,就無法使用 Java 動態代理機制,這時可以透過 cglib(Code Generation Library),它的底層基於 ASM,可於執行時期修改位元組碼、動態生成代理物件。

若要將〈 動態代理〉的專案範例改用 cglib,可以在 gradle.build 中加入相依:


compile 'cglib:cglib-nodep:'3.2.9'

接著實作一個攔截器,它實作了 MethodInterceptor


package cc.openhome.interceptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.logging.Logger;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class LoggingInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object target, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
Logger.getLogger(target.getClass().getName())
.info(String.format("%s.%s(%s)",
target.getClass().getName(), method.getName(), Arrays.toString(args)));
return proxy.invokeSuper(target, args);
}
}

然後 AppConfig 基於 cglib 來建立代理物件:


package cc.openhome;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import cc.openhome.interceptor.LoggingInterceptor;
import cc.openhome.model.AccountDAO;
import net.sf.cglib.proxy.Enhancer;
@Configuration
@ComponentScan
public class AppConfig {
@Autowired
@Qualifier("accountDAOJdbcImpl")
private AccountDAO accountDAO;
@Autowired
private DataSource dataSource;
@Bean(destroyMethod="shutdown")
public DataSource dataSource(){
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:testData.sql")
.build();
}
@Bean
public AccountDAO accountDAO() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(accountDAO.getClass());
enhancer.setCallback(new LoggingInterceptor());
return (AccountDAO) enhancer.create(
new Class[] {DataSource.class},
new Object[] {dataSource}
);
}
}

在進行動態代理時,Spring 底層預設會採用 Java 動態代理,若目標對象沒有實作介面則改用 cglib,實際上,AOP 是個概念,各廠商會有各自的實現,為此, AOP Alliance 定義了一套介面標準, MethodInterceptor 在 AOP Alliance 的定義則是:


package org.aopalliance.intercept;
public interface MethodInterceptor {
Object invoke(MethodInvocation methodInvocation) throws Throwable;
}

若使用 Spring AOP,你也可以實作這個介面,這部份可參考我舊版文件中的 AroundAdvice 中的範例。


原文出處:略談 cglib
前一個主題 | 下一個主題 | | | |

討論串




Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|