• java动态代理


    有两种动态代理来:jdk动态代理和cglib动态代理。

    两种方法同时存在,各有优劣。

      - jdk动态代理是由Java内部的反射机制来实现的

      - cglib动态代理底层则是借助asm来实现的。(asm:是一个JAVA字节码分析、创建和修改的开源应用框架)

        - ASM(1)是一个JAVA字节码分析、创建和修改的开源应用框架。它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。

          在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵活的操作字节码的方式。

          ASM相当小巧,并且它有更高的执行效率,是BCEL的7倍,SERP的11倍以上(摘自网络,具体没有测试)。目前ASM已被广泛的开源应用架构所使用,

          例如:Spring、Hibernate等 

      总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。。

    方法一JDK:

    接口:

    public interface Subject {
        public void rent();
        public void hello(String str);
    }

    实现类:

    public class RealSubject implements Subject {
    
        public void rent() {
            System.out.println("RealSubject rent......");
        }
        public void hello(String str) {
            System.out.println("hello : "+str);
        }
    
    }

    代理类:

    public class DynamicProxy implements InvocationHandler {
    	private Object subject;
    	public DynamicProxy(Object subject){
    		this.subject=subject;
    	}
    	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
    		//在代理真实对象之前,我们可以设置自己的操作
    		System.out.println("在代理真实对象之前.......");
    		System.out.println("method: "+method);
    		//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
    		method.invoke(subject, args);
    	       //在代理真实对象后我们也可以添加一些自己的操作
                   System.out.println("在代理真实对象之后.......");
    		return null;
    	}
    
    }
    

      测试方法:

        public static void main(String[] args) {
            RealSubject realSubject=new RealSubject();
            
            InvocationHandler handler=new DynamicProxy(realSubject);
            Subject subject=(Subject) Proxy.newProxyInstance(
                    realSubject.getClass().getClassLoader(),
                    realSubject.getClass().getInterfaces(), 
              handler); System.out.println(subject.getClass().getName()); subject.rent();
    // subject.hello("你好"); }

    方法二CGLIB:

     http://blog.csdn.net/zhoudaxia/article/details/30591941

  • 相关阅读:
    向TRichEdit插入图片的单元
    等待程序结束后, 自动启动程序的批处理
    执行程序函数
    基于IWICImage的截图代码
    线程中WICImage与Bitmap数据转换
    清理win10过期补丁的命令
    [转] 常见的哈希函数
    豆瓣小组爬虫.....^_^
    如何在ASP.NET Core中实现CORS跨域
    在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证
  • 原文地址:https://www.cnblogs.com/wangleBlogs/p/7443828.html
Copyright © 2020-2023  润新知