CGLIB(CodeGenerationLibrary)是一個開源項目!是一個強大的,高性能,高品質的Code生成類庫,它可以在運作期擴充Java類與實作Java接口。
如果被代理目标對象,沒有實作任何接口,不能用JDK動态代理使,就要選用Cglib 類庫進行動态代理。
Cglib 使用原理流程 和 JDK代理 是類似的
其底層依賴一個工具類org.springframework.cglib.proxy.Enhancer和一個接口org.springframework.cglib.proxy.MethodInterceptor
通過對目标對象類建立子類,覆寫方法,實作代理增強
代碼示例:
CglibProxyUtils.java
package com.my.cglibproxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
//cglib 建立代理 工具類
public class CglibProxyUtils implements MethodInterceptor{
// 目标對象
private Object target;
public CglibProxyUtils(Object target) {
this.target = target;
}
// 建立代理
public Object createProxy(){
// 建立代理 工具類
Enhancer enhancer = new Enhancer();
// 設定父類型Class
enhancer.setSuperclass(target.getClass());
// 設定回調invocation對象
enhancer.setCallback(this);
// 建立代理
return enhancer.create();
}
/*
* proxy 是代理對象
* method 是調用方法反射對象
* args 是調用方法參數
* methodProxy 是調用目标方法代理對象 ,用于調用父類的方法
*
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
System.out.println("cglib 動态代理...");
// return method.invoke(target, args);
return methodProxy.invokeSuper(proxy, args);// 推薦寫法
}
}
ProductDAO.java
package com.my.cglibproxy;
//目标對象
public class ProductDAO {
public void save(){
System.out.println("添加商品...");
}
public void search(){
System.out.println("搜尋商品...");
}
}
Test.java
package com.my.cglibproxy;
public class Test {
// 沒有代理
@org.junit.Test
public void demo1(){
System.out.println("沒有代理");
ProductDAO productDAO = new ProductDAO();
productDAO.save();
productDAO.search();
System.out.println("-----------");
System.out.println();
}
// 使用cglib代理
@org.junit.Test
public void demo2(){
// 目标
System.out.println("使用cglib代理");
ProductDAO productDAO = new ProductDAO();
// 建立代理
CglibProxyUtils cglibProxyUtils = new CglibProxyUtils(productDAO);
ProductDAO proxy = (ProductDAO) cglibProxyUtils.createProxy();
// 執行方法
proxy.save();
proxy.search();
}
}
運作結果: