在spring,hibernate等開源框架中使用了cglib (Code Generation Library),它可以用來動態繼承Java類和實現接口,而Proxy必須基于接口.用google搜索了一下,發現這方面的文檔非常少,除了白衣寫的一篇<cglib的應用>外,另外就是一篇未知源頭的一篇文章,現在我就參考這兩個文章來解析一下cglib的使用
public static void main(String[] args) {
/** style1.增強一個已有類 */
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new MethodInterceptorImpl());
SampleClass sampleClazz1 = (SampleClass) enhancer.create();
sampleClazz1.method1();
/** style2.使用CallbackFilter */
Callback[] callbacks = new Callback[] { new MethodInterceptorImpl(), NoOp.INSTANCE };
Enhancer enhancer2 = new Enhancer();
enhancer2.setSuperclass(SampleClass.class);
enhancer2.setCallbacks(callbacks);
enhancer2.setCallbackFilter(new CallbackFilterImpl());
SampleClass sampleClazz2 = (SampleClass) enhancer2.create();
sampleClazz2.method1();
sampleClazz2.method2();
/** style3.使用Mixin */
Class[] interfaces = new Class[] { SampleInterfaceA.class, SampleInterfaceB.class };
Object[] delegates = new Object[] { new SampleInterfaceAImpl(), new SampleInterfaceBImpl() };
Object obj = Mixin.create(interfaces, delegates);
SampleInterfaceA sampleInterfaceA = (SampleInterfaceA) obj;
sampleInterfaceA.methodA();
SampleInterfaceB sampleInterfaceB = (SampleInterfaceB) obj;
sampleInterfaceB.methodB();
}
private static class CallbackFilterImpl implements CallbackFilter {
/** 返回的值,為指定Callback[]數組中index的值 */
public int accept(Method method) {
if (method.getName().equals("method2"))
return 1;
else
return 0;
}
}
private static class MethodInterceptorImpl implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println(method);
return proxy.invokeSuper(obj, args);
}
}
其中:
public class SampleInterfaceAImpl implements SampleInterfaceA {
public void methodA() {
System.out.println("SampleInterfaceAImpl.methodA()");
}
}
public class SampleInterfaceBImpl implements SampleInterfaceB {
public void methodB() {
System.out.println("SampleInterfaceBImpl.methodB()");
}
}
簡單分析一下:
style1: 最基本的使用示例,在白衣文章中所舉的log例子中已經使用了.
style2: 有多個callback時,利用
CallbackFilter屬性不同的方法可以選擇callback進行執行.
style3: 混合使用,配置好之后可以隨意調用.
附:
Proxy(Java 動態代理相關)1.使用Java 動態代理實現AOP
2.對代理模式與Java動態代理類的理解