动态代理的另一种选择——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();
}
}

代码还是比较清晰的吧,主要就是一个绑定,然后反射调用。在反射调用的前后加上自己的功能增强。


分享到:


相關文章: