| 首先我們來(lái)談?wù)刯dk的動(dòng)態(tài)代理,它允許開發(fā)者在運(yùn)行期創(chuàng)建接口的代理實(shí)例,那么當(dāng)我們?cè)谶\(yùn)行過(guò)程中調(diào)用某個(gè)實(shí)例的某個(gè)方法時(shí),可以使用代理對(duì)象去具體實(shí)現(xiàn)它,從而達(dá)到aop的效果。 (1)jdk的動(dòng)態(tài)代理主要涉及兩個(gè)類:proxy和invocacationHandler,invocationHandler里面包含了橫切邏輯,并且可以使用反射調(diào)用目標(biāo)類的方法(就是切點(diǎn)),proxy類主要是使用它的一個(gè)newinstance方法去創(chuàng)建一個(gè)代理實(shí)例。 下面我們來(lái)看代碼: package com.yue.test;    import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;    public class testHandler implements InvocationHandler{      private Object target;      public testHandler(Object o){          this.target  = o;      }            /*       * 這里的method對(duì)象是java反射機(jī)制中的方法反射類對(duì)象,通過(guò)這個(gè)方法反射對(duì)象可以調(diào)用目標(biāo)對(duì)象中的方法       * 里面的target是目標(biāo)類對(duì)象,利用反射在目標(biāo)類對(duì)象中找到對(duì)應(yīng)的方法傳入?yún)?shù)后調(diào)用       * 也可以說(shuō)是根據(jù)目標(biāo)對(duì)象得到的代理對(duì)象是在目標(biāo)對(duì)象的基礎(chǔ)上插入了橫切邏輯的       * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])       */      @Override      public Object invoke(Object proxy, Method method, Object[] args)              throws Throwable {          System.out.println("hey");          Object obj = method.invoke(target, args);          System.out.println("end!");          return obj;      }    }  
package com.yue.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class testHandler implements InvocationHandler{
	private Object target;
	public testHandler(Object o){
		this.target  = o;
	}
	
	/*
	 * 這里的method對(duì)象是java反射機(jī)制中的方法反射類對(duì)象,通過(guò)這個(gè)方法反射對(duì)象可以調(diào)用目標(biāo)對(duì)象中的方法
	 * 里面的target是目標(biāo)類對(duì)象,利用反射在目標(biāo)類對(duì)象中找到對(duì)應(yīng)的方法傳入?yún)?shù)后調(diào)用
	 * 也可以說(shuō)是根據(jù)目標(biāo)對(duì)象得到的代理對(duì)象是在目標(biāo)對(duì)象的基礎(chǔ)上插入了橫切邏輯的
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("hey");
		Object obj = method.invoke(target, args);
		System.out.println("end!");
		return obj;
	}
}
 package com.yue.test;        public class PrivateCar implements Car{                  public void say(){          System.out.println("spring is fun!");      }  }  
package com.yue.test;
public class PrivateCar implements Car{
	
	
	public void say(){
		System.out.println("spring is fun!");
	}
}
 package com.yue.test;    public interface Car {      public void say();  }  
package com.yue.test;
public interface Car {
	public void say();
}
 package com.yue.test;    import java.lang.reflect.Proxy;          public class Test {        public static void main(String[] args){          PrivateCar pc = new PrivateCar();          testHandler th = new testHandler(pc);          //這里因?yàn)樯傻拇韺?duì)象實(shí)現(xiàn)了目標(biāo)對(duì)象的所有接口,所以根據(jù)多態(tài)可以變?yōu)镃ar類型          Car car = (Car)Proxy.newProxyInstance(pc.getClass().getClassLoader(), pc.getClass().getInterfaces(), th);          car.say();                      }      }  
package com.yue.test;
import java.lang.reflect.Proxy;
public class Test {
	public static void main(String[] args){
		PrivateCar pc = new PrivateCar();
		testHandler th = new testHandler(pc);
		//這里因?yàn)樯傻拇韺?duì)象實(shí)現(xiàn)了目標(biāo)對(duì)象的所有接口,所以根據(jù)多態(tài)可以變?yōu)镃ar類型
		Car car = (Car)Proxy.newProxyInstance(pc.getClass().getClassLoader(), pc.getClass().getInterfaces(), th);
		car.say();
		
	
	}
}
得到的結(jié)果是:
 hey
spring is fun!
end!
 所以我們可以看到,jdk動(dòng)態(tài)代理的局限在于它只是在接口層次上的實(shí)現(xiàn),不能用在子類上
 (2)若要不是用于接口定義,則需要用到cglib代理(這里需要格外引入jar包) cglib代理使用底層的字節(jié)碼技術(shù),可以為一個(gè)類創(chuàng)建子類,并在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用,織入橫切邏輯 下面我們來(lái)看看代碼: package com.yue.test;            public class Test {        public static void main(String[] args){          CglibProxy cp = new CglibProxy();          PrivateCar pc = (PrivateCar)cp.getProxy(PrivateCar.class);          pc.say();      }      }  
package com.yue.test;
public class Test {
	public static void main(String[] args){
		CglibProxy cp = new CglibProxy();
		PrivateCar pc = (PrivateCar)cp.getProxy(PrivateCar.class);
		pc.say();
	}
}
 package com.yue.test;    import java.lang.reflect.Method;    import net.sf.cglib.proxy.Enhancer;  import net.sf.cglib.proxy.MethodInterceptor;  import net.sf.cglib.proxy.MethodProxy;    public class CglibProxy implements MethodInterceptor{      private Enhancer enhancer = new Enhancer();      /*       * 這里的setSuperClass表示創(chuàng)建的代理對(duì)象是這個(gè)類的子類       * create方法表示使用字節(jié)碼的方式創(chuàng)建子類對(duì)象       */      public Object getProxy(Class clazz){          enhancer.setSuperclass(clazz);          enhancer.setCallback(this);          return enhancer.create();      }            /*       * 每個(gè)父類方法的調(diào)用,都會(huì)被這個(gè)intercept方法攔截住,并且織入橫切邏輯       * 這里的methodProxy對(duì)象也是利用java的反射機(jī)制去執(zhí)行父類中的業(yè)務(wù)方法       * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)       */      @Override      public Object intercept(Object arg0, Method arg1, Object[] arg2,              MethodProxy arg3) throws Throwable {          System.out.println("heycglib");          Object obj = arg3.invokeSuper(arg0, arg2);          return obj;      }    }  
package com.yue.test;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor{
	private Enhancer enhancer = new Enhancer();
	/*
	 * 這里的setSuperClass表示創(chuàng)建的代理對(duì)象是這個(gè)類的子類
	 * create方法表示使用字節(jié)碼的方式創(chuàng)建子類對(duì)象
	 */
	public Object getProxy(Class clazz){
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}
	
	/*
	 * 每個(gè)父類方法的調(diào)用,都會(huì)被這個(gè)intercept方法攔截住,并且織入橫切邏輯
	 * 這里的methodProxy對(duì)象也是利用java的反射機(jī)制去執(zhí)行父類中的業(yè)務(wù)方法
	 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
	 */
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		System.out.println("heycglib");
		Object obj = arg3.invokeSuper(arg0, arg2);
		return obj;
	}
}
 總結(jié):由于cglib代理創(chuàng)建代理對(duì)象時(shí)間比jdk代理多了差不多8倍,而創(chuàng)建出來(lái)的代理運(yùn)行速率差不多是jdk創(chuàng)建出來(lái)的10倍,所以一般單例我們都使用cglib代理,prototype就是用jdk代理 
 這里我們還必須注意的是,因?yàn)閖dk動(dòng)態(tài)代理是使用接口創(chuàng)建,cglib動(dòng)態(tài)代理創(chuàng)建的是子類代理,所以: (1)jdk:除public外的所有方法都不可以被增強(qiáng)(注意public static也是不可以的)
 (2)cglib:private,static、final方法都不可以 
 |