• 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方法,无法进行代理


  • 相关阅读:
    PHP:第一章——PHP中字符运算符、比较运算符、错误控制运算符
    PHP:第一章——PHP中逻辑运算符的使用方法
    PHP:第一章——PHP中的算术运算符/递增、递减运算符/赋值运算符
    微信小程序通过js动态修改css样式的方法(交流QQ群:604788754)
    微信小程序跨页面获取数据示例
    JavaEE资源
    java 学习路线
    想以编程为职业,现在正在看毕向东的java基础,接下来应该看什么视频,求前辈们指教。
    2017Java学习路线图,内附完整Java自学视频教程+工具经验+面试
    各种 学习路线图专区
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300336.html
Copyright © 2020-2023  润新知