zoukankan      html  css  js  c++  java
  • java cglib动态代理原理及样例

    

    cglib动态代理:

    http://blog.csdn.net/xiaohai0504/article/details/6832990

    一、原理

          代理为控制要访问的目标对象提供了一种途径。当访问对象时,它引入了一个间接的层。JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。

    二、什么是cglib

         CGLIB是一个强大的高性能的代码生成包。

          1>它广泛的被许多AOP的框架使用,例如:Spring AOP和dynaop,为他们提供方法的interception(拦截);

           2>hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的);

           3>EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。

         它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。

    三、底层

          CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类。除了CGLIB包,脚本语言例如 Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。所以cglib包要依赖于asm包,需要一起导入。


    四、样例

    1. java方式代理

    package cn.jerry.mouse.dynamic_proxy.java;  
      
    public interface IStudent {  
        public void action();  
    }  


    package cn.jerry.mouse.dynamic_proxy.java;  
      
    public class StudentImpl implements IStudent
    {  
        @Override  
        public void action() {  
           System.out.println("[Student]实际方法。。。");  
        }  
      
    }  

    package cn.jerry.mouse.dynamic_proxy.java;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * JDK动态代理代理类
     */
    public class JavaProxy implements InvocationHandler {
    	private Object target;
    
    	/**
    	 * 绑定委托对象并返回一个代理类
    	 * 
    	 * @param target
    	 * @return
    	 */
    	public Object bind(Object target) {
    		this.target = target;
    		// 取得代理对象
    		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
    				target.getClass().getInterfaces(), this); // 要绑定接口
    	}
    
    	@Override
    	/** 
    	 * 调用方法 
    	 */
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		Object result = null;
    		System.out.println("【java代理】调用实际方法前");
    		// 执行方法
    		result = method.invoke(target, args);
    		System.out.println("【java代理】调用实际方法后");
    		return result;
    	}
    
    }
    


    package cn.jerry.mouse.dynamic_proxy.java;  
    
    public class TestProxy {  
     
       public static void main(String[] args) {  
            JavaProxy proxy = new JavaProxy();  
            IStudent student = (IStudent) proxy.bind(new StudentImpl());  
            student.action(); 
        }  
    }  
    

    2.cglib方式代理


    package cn.jerry.mouse.dynamic_proxy.cglib;  
      
    public class StudentImpl
    {  
        public void action() {  
           System.out.println("[Student]实际方法。。。");  
        }  
    }  


    package cn.jerry.mouse.dynamic_proxy.cglib;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    /**
     * 使用cglib动态代理
     * 
     */
    public class CgLibProxy implements MethodInterceptor {
    	private Object target;
    
    	/**
    	 * 创建代理对象
    	 * 
    	 * @param target
    	 * @return
    	 */
    	public Object getInstance(Object target) {
    		this.target = target;
    		Enhancer enhancer = new Enhancer();
    		enhancer.setSuperclass(this.target.getClass());
    		// 回调方法
    		enhancer.setCallback(this);
    		// 创建代理对象
    		return enhancer.create();
    	}
    
    	@Override
    	// 回调方法
    	public Object intercept(Object obj, Method method, Object[] args,
    			MethodProxy proxy) throws Throwable {
    		System.out.println("[cglib代理]调用实际方法前");
    		proxy.invokeSuper(obj, args);
    		System.out.println("[cglib代理]调用实际方法后");
    		return null;
    
    	}
    
    }
    

    package cn.jerry.mouse.dynamic_proxy.cglib;
    
    public class TestProxy {
    
    	public static void main(String[] args) {
    		CgLibProxy cglib = new CgLibProxy();
    		StudentImpl student = (StudentImpl) cglib.getInstance(new StudentImpl());
    		student.action();
    	}
    }
    


    源代码下载:http://download.csdn.net/detail/yinxing2008/7205015


    
  • 相关阅读:
    (二)Knockout 文本与外观绑定
    Knockout案例: 全选
    (一)Knockout 计算属性
    打造Orm经典,创CRUD新时代,Orm的反攻战
    让我们开启数据库无Linq、零sql时代
    EF总结
    高性能Web系统设计方案(初稿目录),支持者进
    Bootstrap+angularjs+MVC3+分页技术+角色权限验证系统
    .NET 2.0 检测
    C# 用代码创建 DataSet 和 DataTable 的列和记录
  • 原文地址:https://www.cnblogs.com/jerry1999/p/3677319.html
Copyright © 2011-2022 走看看