zoukankan      html  css  js  c++  java
  • Cglib动态代理

           JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

    委托类:

    package com.reflect.proxy;
    
    public class GunDog1 {
    	
    	public void info() {
    		System.out.println("我是一只美丽的猎狗");
    	}
    	
    	public void run() {
    		System.out.println("我非常的奔跑迅速");
    	}
    
    }
    

    通用的方法:

    package com.reflect.proxy;
    
    public class DogUtil {
    	
    	
    	public void method1(){
    		System.out.println("=====模拟第1个通用方法======");
    	}
    	
    	public void method2(){
    		System.out.println("=====模拟第2个通用方法======");
    	}
    
    }
    

    代理类“:

    interceptor(Object obj,Method method,Object[] args ,MethodProxy proxy)  是CGLib定义的Interceptor接口的方法,它拦截所有目标类方法的调用 ,obj表示目标类的实例;method为目标类方法的反射对象;args为方法的动态入参;而proxy为代理类方法实例.

    package com.reflect.proxy;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    /**
     * 使用cglib动态代理
     * @author yulei
     *
     */
    public class GunDogCglib implements MethodInterceptor {
    	private Object target;
    	
    	/**
    	 * 创建代理对象
    	 */
    	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 object, Method method, Object[] args,
    			MethodProxy methodProxy) throws Throwable {
    	     DogUtil du=new DogUtil();
    		//执行DogUtil中的method1
    		 du.method1();
    	   Object result=  methodProxy.invokeSuper(object, args);
    		//执行DogUtil中的Method2
    		du.method2();
    		
    		return result;
    	}
    }
    

    测试类:

    package com.reflect.proxy;
    
    public class TestCglib {
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		GunDogCglib dogCglib=new GunDogCglib();
    		GunDog1 gunDog1=(GunDog1) dogCglib.getInstance(new GunDog1());
    		gunDog1.run();
    	}
    
    }
    
    输出:

    =====模拟第1个通用方法======
    我非常的奔跑迅速
    =====模拟第2个通用方法======
    


      CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理


  • 相关阅读:
    Android Eclipse真机调试 过滤器filter没有显示
    Maven in 5 Minutes(Windows)
    接触JETM
    使用mobile.changePage()时出现的问题(转)
    jQuery Mobile页面跳转后未加载外部JS(转)
    iDempiere VS ADempiere
    为Drupal7.22添加富编辑器 on Ubuntu 12.04
    说说iDempiere = OSGi + ADempiere的OSGi
    购买阿里云云服务器( 最小配置)
    安装Drupal7.12升级至7.22
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300336.html
Copyright © 2011-2022 走看看