前面说到了java的动态代理,但是动态代理依赖于接口,这次来看看cglib来实现的代理...
假设有如下方法,这回没有说接口哦~
package proxy.cglibProxy; public class RealSubject2 { public void request() { System.out.println("request..."); } public void response() { System.out.println("response..."); } }
然后,需求来了,希望在执行方法前后加某个其他的操作,这个类没有实现任何接口啊,不能用动态代理了,只好使用cglib了
那么可以这么做:
package proxy.cglibProxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib动态代理 * * */ public class CglibProxy implements MethodInterceptor { private Object target; /** * 创建代理对象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before..."); proxy.invokeSuper(obj, args); System.out.println("afeter..."); return null; } }
然后客户端代码可以这么写:
package proxy.cglibProxy; public class CglibTestMain { public static void main(String[] args) { CglibProxy cglib = new CglibProxy(); RealSubject2 subject = (RealSubject2) cglib.getInstance(new RealSubject2()); subject.request(); } }
如果我们在上面的main方法里面加一行:
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"c:\cglib");
就可以看到编译后的class,你会发现一个RealSubject2$$EnhancerByCGLIB$$d705369d.class
用反编译工具打开看看你就明白了:(这里推荐一个小巧的反编译工具,点我下载 )
public class RealSubject2$$EnhancerByCGLIB$$d705369d extends RealSubject2 implements Factory { ...... }
也就是说,cglib其实通过修改字节码,给没有实现接口的RealSubject2设置了一个继承它的子类....
更多关于cglib的介绍可以看这里: