1. 程式人生 > >SSM(六)JDK動態代理和Cglib動態代理

SSM(六)JDK動態代理和Cglib動態代理

sys .com images 織入 load obj spa -1 instance

1.Cglib動態代理

技術分享

目標類:

 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 }

測試:

 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的構造器。

create()方法是生成代理對象,其本質是目標類的子類實例,所以會調用父類構造。

2.JDK動態代理

jdk動態代理原理是動態生成目標對象實現接口的實現類。

技術分享

接口:

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動態代理要快。

SSM(六)JDK動態代理和Cglib動態代理