说到CGLIB,肯定又想起springAop,但其实springAop并不是 第一个提出aop思想的开源框架,而是一个十分强大的老框架AspectJ, spring的发展过程中,它的开发者 老罗(RodJohnson) 也接受了 别人的建议把 AspectJ 整合到了sprng的阵营,才有了现在的spring的强大,下一次 我说下 spring的Aop和 AspectJ 有什么区别。
这次我们的主角还是CGLIB, 这是aop的神器,用起来真的很爽,我们一起来看看该如何使用吧,看代码。
//接口
public interface Hello { public void say(String name); }
//实现类
public class HelloImpl implements Hello{ public void say(String name) { System.out.println(name); } }
CGLIB代理类,此处还是提供了 一个getProxy的方法,解决转型问题
public class CGLIBProxy implements MethodInterceptor { public T getProxy(Class cls) { //传进来 需要被代理对象的类类型 return (T) Enhancer.create(cls, this); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object object = methodProxy.invokeSuper(o, objects); after(); return object; } public void before(){ System.out.println("before"); } public void after(){ System.out.println("after"); } }
//测试类
@org.junit.Test public void a(){ CGLIBProxy cglibProxy = new CGLIBProxy(); HelloImpl proxy = cglibProxy.getProxy(HelloImpl.class); proxy.say("无声落叶"); }
console:
before
无声落叶
after
看到结果代码就懂了,但是 这样的 调用方式还是很麻烦,我们来重构下吧,
//重构后的 CGLIB 代理类
public class CGLIBProxy implements MethodInterceptor { private static CGLIBProxy cglibProxy; public static CGLIBProxy getInstance(){ return cglibProxy; } public T getProxy(Class cls) { //传进来 需要被代理对象的类类型 return (T) Enhancer.create(cls, this); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object object = methodProxy.invokeSuper(o, objects); after(); return object; } public void before(){ System.out.println("before"); } public void after(){ System.out.println("after"); } }
//以上 使用到了 单例模式,两行代码即可调用
@org.junit.Test public void a(){ HelloImpl proxy = CGLIBProxy.getInstance().getProxy(HelloImpl.class); proxy.say("无声落叶"); }
值得一说的是CGLIB是基于方法层的代理,Jdk的代理是基于类的,并且CGLIB也有它的局限性,CGLIB本质是继承了被代理类来实现的 代理,所以当被代理类 被final修饰或是方法被fianl或static修饰,那么就会报错,被final修饰的类不可被继承,被static修饰的方法不可被覆盖。
写代码 就是喜欢简洁,再见