[zt] cglib2 proxy tutorial
来源:互联网 发布:域名续费期 编辑:程序博客网 时间:2024/05/24 22:42
http://www.cnblogs.com/findsun/
for those that are familiar with aop will have most certainly heard of cglib. for those that have not, cglib provides the ability instrument bytecode programmatically. it uses asm for the heavy lifting, and provides a simple interface to extend any non-final class as well as implement interfaces at runtime. i myself am rather new to cglib and cglib2 and have found examples rather lacking so i have decided to put together an example that concisely shows all of the power of cglib2's proxying prowess. if anyone finds this useful i might put together additional tutorials as well. please feel free to submit feedback.
unfortunately the cglib website does not do a very good job of selling the power of it's library. the documentation is scarce, the examples are thin, and i was is left scratching my head as to exactly how to utilize this powerful tool. fortunately the test cases are rather complete so after digging around i was able to piece together almost all of the proxying power of cglib. the example below will begin with several simple classes that we can either extend of implement with cglib -- below i will outline how to intercept methods, add mixins, and make proxies "aware" with the cglib Enhancer.
first we start with several simple interfaces Foo, Bar, and FooBar.
public interface Foo { public void foo();}public interface Bar { public void bar();}public interface FooBar extends Foo, Bar {}
next we provide very simple implementations of the Foo and Bar interfaces.
import java.io.Serializable;public class FooImpl implements Foo, Serializable { public void foo() { System.out.println("foo"); }}import java.io.Serializable;public class BarImpl implements Bar, Serializable { public void bar() { System.out.println("bar"); }}
next we provide a simple interceptor implementation to log method calls.
public class LoggingInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { try { System.out.println("before " + method); return proxy.invokeSuper(obj, args); } finally { System.out.println("after " + method); } }}
once this is done we can instruct cglib to enhance our classes accordingly. the first example shows how we can extend the superclass FooImpl by implementing the Bar interface and dispatch to the implementation and intercepting method calls. you will also notice that we are instructing cglib to implement the FooBar interface -- the purpose is to consolidate our interfaces into one "aware" interface so we do not have to cast to each interface cglib implemented for us.
public void testExtendingSuperclass() throws Exception { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(FooImpl.class); enhancer.setInterfaces(new Class[] { Bar.class, FooBar.class }); enhancer.setCallbackTypes(new Class[] { Dispatcher.class, MethodInterceptor.class }); enhancer.setCallbackFilter(new CallbackFilter() { public int accept(Method method) { if (Bar.class.isAssignableFrom(method.getDeclaringClass())) return 0; else return 1; } }); Class clazz = enhancer.createClass(); enhancer.registerCallbacks(clazz, new Callback[] { new Dispatcher() { public Object loadObject() { return Enhancer.create(BarImpl.class, new LoggingInterceptor()); } }, new LoggingInterceptor() }); FooBar foobar = (FooBar) clazz.newInstance(); foobar.foo(); foobar.bar();}
the next example shows how we can have cglib create a new Class for us without extending a superclass. in this example we are dispatching to all the implementation that cglib has implemented for us.
public void testNoSuperclass() throws Exception { Enhancer enhancer = new Enhancer(); enhancer.setInterfaces(new Class[] { Foo.class, Bar.class, FooBar.class }); enhancer.setCallbackTypes(new Class[] { Dispatcher.class, Dispatcher.class }); enhancer.setCallbackFilter(new CallbackFilter() { public int accept(Method method) { return Foo.class.isAssignableFrom( method.getDeclaringClass()) ? 0 : 1; } }); /* enhancer.setStrategy(new DefaultGeneratorStrategy() { protected byte[] transform(byte[] b) { try { FileOutputStream fos = new FileOutputStream("build/Cglib2Generated.class"); fos.write(b); } catch (Exception e) { e.printStackTrace(); } return b; } }); */ Class clazz = enhancer.createClass(); enhancer.registerCallbacks(clazz, new Callback[] { new Dispatcher() { public Object loadObject() { return Enhancer.create(FooImpl.class, new LoggingInterceptor()); } }, new Dispatcher() { public Object loadObject() { return Enhancer.create(BarImpl.class, new LoggingInterceptor()); } } }); FooBar foobar = (FooBar) clazz.newInstance(); foobar.foo(); foobar.bar();}
with these simple examples we are on our way to fully utilizing the power of cglib proxies. you may also notice that i have commented out setting the strategy in the second example. this is a very powerful undocumented feature that allows us to directly access the byte[] of our proxy. i hope this provides some valuable insight into how you can use cglib to it's fullest.
- [zt] cglib2 proxy tutorial
- [zt] cglib2 proxy tutorial
- Cannot proxy target class because CGLIB2 is not available
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the...
- spring使用中报Cannot proxy target class because CGLIB2 is not available错
- [Sprincglib] spring aop报错:Cannot proxy target class because CGLIB2 is not available.
- Spring 错误Cannot proxy target class because CGLIB2 is not available
- spring aop报错:Cannot proxy target class because CGLIB2 is not available.
- UIAppearance Proxy Protocol Tutorial/Example
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify pr
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify pr
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify pr
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify pr
- Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify pr
- [zt] hashing table and Data Structure tutorial
- (ZT)MS Active Template Library (ATL) Tutorial
- CGLIB2的错误
- zt
- 在小型项目中使用 IBM Rational Unified Process: 极限编程剖析
- 查看SQL SERVER 加密存储过程,函数,触发器,视图
- 通用数据分页类
- IT 架构和应用程序的端到端测试
- QQ消息轰炸机源代码(VB.NET)
- [zt] cglib2 proxy tutorial
- 4个GMail邀请,先到先得
- 昨天的Oracle操作处理笔记
- serverVariables参数
- 数据库设计经验浅谈一
- SOHO开始的第一个问题--团队建设
- VC++中使用内存映射文件处理大文件
- 在WEB自定义控件中实现自动回传功能
- 过劳死----IT界杀手