源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

java动态代理和cglib动态代理示例分享

  • 时间:2022-11-22 03:48 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:java动态代理和cglib动态代理示例分享
java动态代理类可以分为两种。 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 动态代理:在程序运行时,运用反射机制动态创建而成。 一、首先我们进行java动态代理的演示。 现在我们有一个简单的业务接口Saying,如下:
[u]复制代码[/u] 代码如下:
package testAOP; public interface Saying { public void sayHello(String name);    public void talking(String name); }
一个简单的实现类SayingImpl,如下:
[u]复制代码[/u] 代码如下:
package testAOP; public class SayingImpl implements Saying {     @Override     public void sayHello(String name) {         // TODO Auto-generated method stub         System.out.println(name + ":大家好啊!");     }     @Override     public void talking(String name) {         // TODO Auto-generated method stub         System.out.println(name + ":我的意思是,我们要努力建设和谐社会!");     } }
我们要实现的是,在sayHello和talking之前和之后分别动态植入处理。 JDK动态代理主要用到java.lang.reflect包中的两个类:Proxy和InvocationHandler. InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑和业务逻辑编织在一起。 Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。 如下,我们创建一个InvocationHandler实例:
[u]复制代码[/u] 代码如下:
package testAOP; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler {     private Object target;     MyInvocationHandler(Object target){         this.target = target;     }     @Override     public Object invoke(Object proxy, Method method, Object[] args)             throws Throwable {         //目标方法前执行         System.out.println("——————————————————————————");         System.out.println("下一位请登台发言!");         //目标方法调用         Object obj = method.invoke(target, args);         //目标方法后执行         System.out.println("大家掌声鼓励!");         return obj;     } }
下面是测试:
[u]复制代码[/u] 代码如下:
package testAOP; import java.lang.reflect.Proxy; public class JDKProxyTest {     public static void main(String[] args) {         // 希望被代理的目标业务类         Saying target = new SayingImpl();         // 将目标类和横切类编织在一起         MyInvocationHandler handler = new MyInvocationHandler(target);         // 创建代理实例         Saying proxy = (Saying) Proxy.newProxyInstance(                 target.getClass().getClassLoader(),//目标类的类加载器                 target.getClass().getInterfaces(),//目标类的接口                 handler);//横切类         proxy.sayHello("小明");         proxy.talking("小丽");     } }
运行情况如下:
[u]复制代码[/u] 代码如下:
—————————————————————————— 下一位请登台发言! 小明:大家好啊! 大家掌声鼓励! —————————————————————————— 下一位请登台发言! 小丽:我的意思是,我们要努力建设和谐社会! 大家掌声鼓励!
使用JDK动态代理有一个很大的限制,就是它要求目标类必须实现了对应方法的接口,它只能为接口创建代理实例。我们在上文测试类中的Proxy的newProxyInstance方法中可以看到,该方法第二个参数便是目标类的接口。如果该类没有实现接口,这就要靠cglib动态代理了。 CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势植入横切逻辑。 二、接下来我们进行cglib动态代理的演示。 首先我们需要导包,我用的包是cglib-nodep-2.1_3.jar。 我们首先创建一个代理创建器CglibProxy:
[u]复制代码[/u] 代码如下:
package testAOP.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{     Enhancer enhancer = new Enhancer();     public Object getProxy(Class clazz) {         //设置需要创建的子类         enhancer.setSuperclass(clazz);         enhancer.setCallback(this);         //通过字节码技术动态创建子类实例         return enhancer.create();     }     @Override     public Object intercept(Object obj, Method method, Object[] args,             MethodProxy proxy) throws Throwable {         // TODO Auto-generated method stub         System.out.println("——————————————————————————");         System.out.println("下一位请登台发言!");         //目标方法调用         Object result = proxy.invokeSuper(obj, args);         //目标方法后执行         System.out.println("大家掌声鼓励!");         return result;     }    }
然后进行测试:
[u]复制代码[/u] 代码如下:
package testAOP.cglib; import testAOP.Saying; import testAOP.SayingImpl; public class CglibProxyTest {     public static void main(String[] args) {         CglibProxy proxy = new CglibProxy();         //通过动态生成子类的方式创建代理类         Saying target = (Saying) proxy.getProxy(SayingImpl.class);         target.sayHello("小明");         target.talking("小丽");     } }
结果与JDK动态代理没有任何区别。 JDK动态代理和CGLib动态代理都是运行时增强,通过将横切代码植入代理类的方式增强。与此不同的是AspectJ,它能够在通过特殊的编译器在编译时期将横切代码植入增强,这样的增强处理在运行时候更有优势,因为JDK动态代理和CGLib动态代理每次运行都需要增强。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部