做一个合格的程序猿之浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理

Spring AOP的核心就是动态代理,我们先来准备下动态代理的知识的储备


  动态代理,顾名思义,就是为一个真实对象生成一个代理的对象,生活中,这种模式也是很常见,例如,淘宝,就是一个代理,很多网店,依托于淘宝,可以更好的卖出很多的产品,但淘宝可能会额外的多做一点事情,这样就会产生双赢的局面


好了,我们现在就根据上面的背景,写下两种代理:


首先jdk的动态代理:

首先定义一个网店的接口

package org.study.spring.aop.jdkdynamicproxy;

/**
 * 
 * jdk的动态代理必须是面向接口的
 * 定义一个淘宝网店的接口
 * @author lyncc
 *
 */
public interface OnlineShop {
	
    /**
     * 网店抽象:用户给钱买东西
     * @param money
     */
	void sellSomething(double money);

}
然后一个网店是卖茶叶的,实现该接口

package org.study.spring.aop.jdkdynamicproxy;

public class TeaOnlineShop implements OnlineShop{

	public void sellSomething(double money) {
		System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");
	}

}
好了,淘宝代理出场了

package org.study.spring.aop.jdkdynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 淘宝代理 jdk的代理要实现InvocationHandler的接口
 * @author lyncc
 *
 */
public class TaobaoProxy implements InvocationHandler{
	
    /**
     * 被代理的对象
     */
	 private Object proxied;   
     
	 public TaobaoProxy(Object proxied){   
	    this.proxied = proxied;   
	 } 

	 /**
	  * InvocationHandler的核心方法,invoke方法
	  */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
	    //马云爸爸表示收到的钱先放在淘宝,来提高GMV
		System.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");
		
		return method.invoke( proxied, args);  
	}

}
测试类

package org.study.spring.aop.jdkdynamicproxy;

import java.lang.reflect.Proxy;

import org.junit.Test;

public class JdkDynamicProxyTest {
	
	
	@Test
	public void test1(){
	     //被代理的对象
		 TeaOnlineShop teaShop = new TeaOnlineShop();   
		 //Proxy 入参三个 加载器,class文件, 实现innovationhandler接口的代理对象
		 OnlineShop shop = (OnlineShop)Proxy.newProxyInstance(OnlineShop.class.getClassLoader(), 
		     new Class[]{OnlineShop.class}, 
		     new TaobaoProxy(teaShop));
		         
		 shop.sellSomething(20d);
	}

}
运行结果:




CGLIB的实现

package org.study.spring.aop.cglib;

/**
 * cglib不需要定义接口,直接给出具体实现
 * @author lyncc
 */
public class TeaOnlineShop{

	public void sellSomething(double money) {
		System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");
	}

}

taobaoProxy

package org.study.spring.aop.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要实现MethodInterceptor接口
 * @author lyncc
 *
 */
public class TaobaoProxy implements MethodInterceptor{
	
	private Enhancer enhancer = new Enhancer();  
	
	public Object getProxy(Class clazz){  
	  //用enhancer 重新编制传入的class的对象
	  enhancer.setSuperclass(clazz);  
	  //回调实现CallBack接口的类(MethodInterceptor基础于CallBack)此处就是回调TaobaoProxy
	  enhancer.setCallback(this);  
	  return enhancer.create();  
	 }

	/**
	 * 拦截器
	 */
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		
		  System.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");
		  
		  Object result = proxy.invokeSuper(obj, args);  
		  return result; 
	}	 

}
测试

package org.study.spring.aop.cglib;

import org.junit.Test;

public class CgLibProxyTest {
	
	@Test
	public void test(){
		TaobaoProxy proxy = new TaobaoProxy();  
		//通过生成子类的方式创建代理类  
		TeaOnlineShop shopProxy = (TeaOnlineShop)proxy.getProxy(TeaOnlineShop.class);  
		shopProxy.sellSomething(21d); 
	}

} 

运行结果:





你可能感兴趣的:(spring源码,Spring源码浅析,dynamicproxy,cglib,动态代理)