Cglib与动态代理代码样例

    Cglib基于字节码生成功能(类似于jdk proxy),提供了简单但是强大的动态代理的能力.代码样例基于cglib-2.1.3和asm-1.5.3:

 

1. Proxy动态代理:

 

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
TestObject orignal = new TestObject();
//基于接口代理
//底层仍基于Enhancer类
TestInterface proxy = (TestInterface)Proxy.newProxyInstance(classLoader, new Class[]{TestInterface.class}, new TestInvocationHandler(orignal));
proxy.testPrint("I am proxy");

 

static class TestInvocationHandler implements InvocationHandler{
	private TestInterface orignal;//被代理类对象,
	TestInvocationHandler(TestInterface orignal){
		this.orignal = orignal;
	}
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//around
		System.out.println("before invoked ");
		Object result = method.invoke(orignal, args);
		System.out.println("after invoked");
		return result;
	}
	
}

/**
 * 接口,需要为public
 *
 */
public static interface TestInterface{
	public void testPrint(String message);
}

static class TestObject implements TestInterface{

	public void testPrint(String message) {
		System.out.println(message);
	}
	
}

    Cglib的proxy几乎和jdk proxy一样,无论是在api还是设计思路上..二者没有太多的差异性.对于cglib-proxy,底层仍然基于Enhance类做辅助操作(更底层仍然是字节码Generator),仍然是生成Proxy类($Proxy),代理的方式仍然是基于"接口列表"和InvocationHandler.

 

 

2. Enhancer动态代理与方法拦截:

 

//使用TestObject类的默认构造函数,创建代理类实例,此代理类支持"方法拦截"
//Enhance不仅支持基于接口列表的方式创建代理类,还支持使用"基类"的方式创建.
Callback interceptor = new TestMethodInterceptor();
//底层仍基于Generator来创建代理类(class)且被缓存
TestObject proxy = (TestObject)Enhancer.create(TestObject.class, interceptor);
proxy.testMethod();

 

Callback interceptor = new TestMethodInterceptor();
//指定构造函数,创建代理类实例
Enhancer enhancer = new Enhancer();
enhancer.setCallback(interceptor);
enhancer.setSuperclass(TestObject.class);
//使用构造函数TestObject(String name)
TestObject proxy = (TestObject)enhancer.create(new Class[]{String.class}, new Object[]{"zhangsan"});
proxy.testMethod();

 

static class TestMethodInterceptor implements MethodInterceptor{

	/**
	 * @param obj 代理对象
	 * @param method 调用的方法,基于jdk reflect,此方法不能直接在当前对象中使用,只能使用在其他实例上,否则将无限循环触发"拦截器"
	 * @param proxy 经过封装的代理类的方法
	 */
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println("here");
		//执行当前代理对象的方法
		proxy.invokeSuper(obj, args);
		TestObject other = new TestObject("lisi");
		//如下两个方法,不能在当前代理对象中使用.
		method.invoke(other, args);
		proxy.invoke(other, args);
		return null;
	}
	
}

    Enhancer是cglib中用于创建动态代理类的辅助类,它和Proxy类比较起来,不仅能够支持"接口列表"代理,还能支持基于"基类"的代理:

enhancer.setSuperclass(TestObject.class);

 

Enhancer主要是用来创建"AOP"外观的代理类,它支持了方法拦截特性.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cglib是一个强大的Java字节码处理库,它可以在运行时生成一个被代理的子,并且拦截目标方法,实现动态代理。 下面是一个简单的cglib实现动态代理代码实例: ``` import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final 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 " + method.getName() + " method execute!"); Object result = proxy.invokeSuper(obj, args); System.out.println("after " + method.getName() + " method execute!"); return result; } public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); UserServiceImpl userService = (UserServiceImpl) cglibProxy.getInstance(new UserServiceImpl()); userService.addUser(); } } ``` 在上面的代码中,CglibProxy实现了MethodInterceptor接口,并实现了intercept方法,用于拦截目标方法的调用。在main方法中,我们可以看到通过cglib Proxy获取了UserServiceImpl的代理对象,并且成功地调用了addUser方法。 希望这个例子能够帮助你更好地理解cglib实现动态代理的原理以及代码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值