zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    持有你自己的权力
    《活在恩典中》:我们所寻求的是什么?
    修学文钞 | 道证法师怎么学印光大师《文钞》
    致初学者:印祖文钞修学次第建议
    印光大师指定的文钞入门篇目
    sql注入在线检测(sqlmapapi)
    【转】Kali Linux 新手折腾笔记
    JAVA开发-我的第一个webScan扫描器
    JAVA开发--游戏24点
    JAVA开发--U盘EXE恢复工具
  • 原文地址:https://www.cnblogs.com/wangleBlogs/p/7443828.html
Copyright © 2011-2022 走看看