動態代理的另一種選擇——cglib

動態代理的另一種選擇——cglib

動態代理的另一種選擇——cglib

在上一篇中,我們的動態代理用的是JDK的實現。JDK的動態代理的特點相比小夥伴們已經注意到了,那就是被代理的類必須是實現了某個接口。newProxyInstance函數接受的是一個Interface型的數組。但在實際工作中,並不是所有類都會給你實現一個接口,如果遇到這種情況,JDK的動態代理就無法使用了。這是這種代理最大的弊端。

動態代理的另一種選擇——cglib

cglib出馬

這種情況下就需要cglib出馬了。

cglib實現動態代理的特點是針對類進行代理。具體來說是,cglib會對要被代理的類生成一個繼承子類,在子類中對方法進行增強。關鍵點就在繼承,所以無法對final類使用。

代碼舉例:

現在cglib已經繼承到spring裡了,不需要再依賴其他包。

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibDemo {
public static void main(String[] args)
{
RealSubject realSubject = new RealSubject ();
ProxySubject proxySubject = new ProxySubject();
RealSubject proxy = (RealSubject) proxySubject.bind(realSubject);
System.out.println(proxy.sayhi());
}
}
// 被代理的原始類
class RealSubject
{
public String sayhi()
{
return "Welcome yunsheng's blog";
}
}
// 代理類
class ProxySubject
{
Object obj;
// 關鍵方法--和原始類綁定
public Object bind(final Object target)
{
this.obj = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
// 通過callback,反射調用到原始類的方法

enhancer.setCallback(new MethodInterceptor()
{
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable
{
// 在反射調用前,進行功能增強
System.out.println("I'm proxy!");
Object res = method.invoke(target, args);
return res;
}
});
return enhancer.create();
}
}

代碼還是比較清晰的吧,主要就是一個綁定,然後反射調用。在反射調用的前後加上自己的功能增強。


分享到:


相關文章: