在上一篇中,我们的动态代理用的是JDK的实现。JDK的动态代理的特点相比小伙伴们已经注意到了,那就是被代理的类必须是实现了某个接口。newProxyInstance函数接受的是一个Interface型的数组。但在实际工作中,并不是所有类都会给你实现一个接口,如果遇到这种情况,JDK的动态代理就无法使用了。这是这种代理最大的弊端。
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(); } }
代码还是比较清晰的吧,主要就是一个绑定,然后反射调用。在反射调用的前后加上自己的功能增强。
本文暂时没有评论,来添加一个吧(●'◡'●)