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

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

相關文章
相關標籤/搜索