1.Cglib動態代理java
目標類:app
1 package cn.happy.proxy.cglib; 2 3 public class Service { 4 public Service() { 5 System.out.println("建立Service對象"); 6 } 7 8 public void doWordk(){ 9 System.out.println("do something"); 10 } 11 }
測試:ide
1 package cn.happy.proxy.cglib; 2 3 import net.sf.cglib.proxy.Enhancer; 4 import net.sf.cglib.proxy.MethodInterceptor; 5 import net.sf.cglib.proxy.MethodProxy; 6 7 import java.lang.reflect.Method; 8 9 public class CglibTest { 10 public static void main(String[] args) { 11 //對方法加強。開閉原則-對修改關閉,對添加放開 12 //1.建立一個目標對象 13 Service service=new Service(); 14 //2.Enhancer對象 15 Enhancer enhancer=new Enhancer(); 16 enhancer.setSuperclass(service.getClass()); 17 //3.調度setCallBack() 18 enhancer.setCallback(new MethodInterceptor() { 19 @Override 20 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 21 System.out.println("write log"); 22 methodProxy.invoke(service,objects); 23 return null; 24 } 25 }); 26 //4.Enhancer對象的Create()方法建立代理 27 Service proxy =(Service) enhancer.create(); 28 //5.執行代理方法 29 proxy.doWordk(); 30 } 31 }
測試結果:測試
測試第27行enhancer.create()方法調用了Service的構造器。spa
create()方法是生成代理對象,其本質是目標類的子類實例,因此會調用父類構造。代理
2.JDK動態代理code
jdk動態代理原理是動態生成目標對象實現接口的實現類。對象
接口:blog
1 package cn.happy.proxy.jdk; 2 3 public interface IService { 4 public void doWordk(); 5 }
目標類:接口
1 package cn.happy.proxy.jdk; 2 3 public class ServiceImpl implements IService{ 4 public ServiceImpl() { 5 System.out.println("建立Service對象"); 6 } 7 @Override 8 public void doWordk(){ 9 System.out.println("do something"); 10 } 11 }
測試:
1 package cn.happy.proxy.jdk; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 public class JdkTest { 8 public static void main(String[] args) { 9 ServiceImpl service = new ServiceImpl(); 10 IService proxy = (IService)Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), new InvocationHandler() { 11 @Override 12 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 13 System.out.println("write log"); 14 method.invoke(service, args); 15 return null; 16 } 17 }); 18 proxy.doWordk(); 19 } 20 }
測試結果:
3.比較
這裏從網上摘了點兒東西
JDK動態代理:代理類和目標類必須實現相同的接口,客戶端經過代理類來調用目標方法,代理類會將全部的方法調用分派到目標對象上反射執行,還能夠在分派過程當中添加"前置通知"和後置處理。
CGLIB動態代理:動態生成一個要代理類的子類,子類重寫要代理的類的全部不是final的方法。在子類中採用方法攔截的技術攔截全部父類方法的調用,順勢織入橫切邏輯。它比使用java反射的JDK動態代理要快。