• 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


    
  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/jerry1999/p/3677319.html
Copyright © 2020-2023  润新知