当前位置:  编程技术>java/j2ee

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

    来源: 互联网  发布时间:2014-11-04

    本文导语:  java动态代理类可以分为两种。 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 动态代理:在程序运行时,运用反射机制动态创建而成。一、首先我们进行j...

java动态代理类可以分为两种。

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

动态代理:在程序运行时,运用反射机制动态创建而成。


一、首先我们进行java动态代理的演示。

现在我们有一个简单的业务接口Saying,如下:

代码如下:

package testAOP;
public interface Saying {
public void sayHello(String name);   
public void talking(String name);
}

一个简单的实现类SayingImpl,如下:

代码如下:

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实例:

代码如下:

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;
    }
}

下面是测试:

代码如下:

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("小丽");
    }
}

运行情况如下:

代码如下:

——————————————————————————
下一位请登台发言!
小明:大家好啊!
大家掌声鼓励!
——————————————————————————
下一位请登台发言!
小丽:我的意思是,我们要努力建设和谐社会!
大家掌声鼓励!

使用JDK动态代理有一个很大的限制,就是它要求目标类必须实现了对应方法的接口,它只能为接口创建代理实例。我们在上文测试类中的Proxy的newProxyInstance方法中可以看到,该方法第二个参数便是目标类的接口。如果该类没有实现接口,这就要靠cglib动态代理了。

CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势植入横切逻辑。

二、接下来我们进行cglib动态代理的演示。

首先我们需要导包,我用的包是cglib-nodep-2.1_3.jar。

我们首先创建一个代理创建器CglibProxy:

代码如下:

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;
    }   
}

然后进行测试:

代码如下:

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动态代理每次运行都需要增强。


    
 
 

您可能感兴趣的文章:

  • java代理 jdk动态代理应用案列
  • java 静态代理 动态代理深入学习
  • 请问各位高手,如何用JAVA编一个代理服务器。
  • 如何用Java做代理,在线等待!!
  • Java类动态代理框架 Smartproxy
  • Java 的 MQTT 代理 Moquette-mqtt
  • Java的HTTP代理服务器 Smart Cache
  • Java动态代理 CGLib
  • 如何代理SUN 的JAVA认证和考试,DJLIHAO@SINA.COM,请将相关协议发到此信箱。500分,在线等
  • 如何代理SUN 的JAVA认证和考试,DJLIHAO@SINA.COM,请将相关协议发到此信箱。500分,在线等
  • 如何代理SUN 的JAVA认证和考试,DJLIHAO@SINA.COM,请将相关协议发到此信箱。500分,在线等
  • 用java开发一个基于Proxy(代理)的网络计费系统。有兴趣的来讨论讨论
  • java代理模式与动态代理模式详解
  • 通用 Java 监控代理 Zorka
  • 代理角色java设计模式之静态代理详细介绍
  • 和Java版高手在线讨论代理服务器的问题,讨论者都有分。
  • java实现动态代理示例分享
  • Java动态代理实现AOP
  • java实现动态代理方法浅析
  • java动态代理示例分享
  • 动态 Java 库 orekit
  • Java动态跟踪分析工具 BTrace
  • 如何使用JAVA调用利用用VC写的已有的动态库
  • ****请你回答:最近java上面有什么动态阿?
  • 请问再java中怎样定义动态数组?
  • 怎样用java调用DLL动态连接库?
  • java中如何实现二维(多维)动态数组.谢谢
  • 请问在java中如何实现类的动态生成?谢谢
  • 如何在java程序中获得拨号上网分配的动态IP?
  • java能否动态开辟string数组?
  • 动态的可以用java吗?
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • andriod下java socket网络编程:java socket客户端服务端代码示例
  • 输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程
  • java Servlet实现Session创建存取以及url重写代码示例
  • java 四舍五入使java保留2位小数示例讲解
  • java进行error捕获和处理示例(java异常捕获)
  • java去除集合中重复元素示例分享 java去除重复
  • java读取csv文件示例分享(java解析csv文件)
  • java求三个数的最大值的示例分享
  • java生成字母数字组合的随机数示例 java生成随机数
  • java实现网页解析示例
  • java协变返回类型使用示例
  • 使用java执行定时任务示例
  • java自定义枚举转换器示例
  • java向文件末尾添加内容示例分享
  • java正则表达式获取url的host示例
  • java使用正则表达校验手机号码示例(手机号码正则)
  • java实现jframe透明窗体示例
  • java的split方法使用示例
  • java抓取网页数据示例
  • Oracle 使用Java Source 简单示例
  • java自定义日期转化类示例
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 如何将java.util.Date转化为java.sql.Date?数据库中Date类型对应于java的哪个Date呢
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3