面試十一、spring的AOP和IOC,底層原理


參考鏈接:https://blog.csdn.net/liyifan687/article/details/90678729

 

1、AOP

  1.1、面向切面編程,可分為靜態代理和動態代理

  1.2、3個實現

    AspectJ:靜態代理,我們在編寫一段獨立業務代碼時可以使用aspectj將邏輯加入

          業務方法中(比如常用的操作日志記錄),在編譯后我們的class文件會

          多出一段代碼,這段代碼就是aspectj在編譯時增加的aop代碼。這種做法可以稱為靜態代理

           代理類在調用被代理類方法前后增加一些切面邏輯。

 

 

    JDK動態代理:使用jdk的反射機制來完成aop的動態代理,有如下要求:

            1)被代理類(我們實現業務的類)要實現統一接口

            2)代理類要實現reflect包里面的InvacationHandler

            3)通過jdk proxy提供的靜態方法newProxyInstance(xxx)來動態創建代理類

              注:proxy是jdk動態生成的代理類,和service屬於同一個類,

                但是save方法被動用時jdk為我們自動的實現類切面邏輯。

           使用jdk反射機制,生成一個繼承Proxy的代理類。實現了InvocationHandler接口,

           在調用方法時實際會先經過invoke方法轉發,所以可以在invoke方法上增加一些切面邏輯

 

 

 1 // 統一接口
 2 public interface IService {
 3     void save();
 4 }
 5 
 6 // 接口實現類
 7 public class UserService implements IService{
 8     @Override
 9     public void save() {
10         System.out.println("save a user ...");
11     }
12 }
13 
14 // 實現InvacationHandler
15 public class MyHandler implements InvocationHandler {
16     private Object target;
17 
18     MyHandler(Object target) {
19         this.target = target;
20     }
21     //在這里實現我們的切面邏輯
22     @Override
23     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
24         System.out.println("before ...");
25         Object result = method.invoke(target, args);
26         System.out.println("after ...");
27         return result;
28     }
29 }
30 
31 // 客戶端代碼
32     public static void main(String[] args) {
33         //創建被代理類
34         IService service = new UserService();
35         //新建代理類,將被代理類注冊到里面
36         MyHandler aop = new MyHandler(service);
37         //Proxy為MyHandler動態創建一個符合某一接口的代理實例
38                 //第一個參數:獲取被代理類的class loader
39                 //第二個參數:獲取被代理類實現的接口, 由此可見被代理類需要實現統一的接口
40                 //第三個參數:InvocationHandler的實例, 也就是我們做切面邏輯的類
41         IService proxy = (IService) Proxy
42                 .newProxyInstance(service.getClass().getClassLoader(),
43                         service.getClass().getInterfaces(),
44                         aop);
45                 //調用代理方法
46         proxy.save();
47     }
48 
49 // 輸出結果
50 before
51 save user
52 after

    GGLIB:全稱Code Generation LIbrary,代碼生產庫。

        基於字節碼技術,修改被代理類的.class文件生成代理類的子類,並重寫了代理類的方法。

        實現了MethodInterceptor接口,在interceptor方法里增加切面邏輯

 

 

 1 // 定義被代理類
 2 public class UserService{
 3     public void save() {
 4         System.out.println("save a user ...");
 5     }
 6 }
 7 
 8 // 實現MethodInterceptor接口(切面邏輯)
 9 public class UserProxy implements MethodInterceptor {
10     @Override
11     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
12         //方法執行前的邏輯
13         System.out.println("before ...");
14         e
15         Object result = methodProxy.invokeSuper(o, objects);
16         //方法執行后的邏輯
17         System.out.println("after ...");
18         return result;
19     }
20 }
21 
22 // 獲取被代理類工廠,該工廠專門生產加入了切面的被代理類
23 public class UserServiceFactory {
24     public static UserService getInstance(UserProxy proxy) {
25         Enhancer enhancer = new Enhancer();
26         enhancer.setSuperclass(UserService.class);
27         //設置回調類,強化類調用回調類中的intercept方法來執行我們定義好的切面邏輯
28         enhancer.setCallback(proxy);
29         //返回一個添加了切面邏輯的增強類
30         return (UserService) enhancer.create();
31     }
32 }
33 
34 // 客戶端調用
35     public static void main(String[] args) {
36         UserProxy proxy=new UserProxy();
37         //通過工廠方法模式獲取增強類
38         UserService service = UserServiceFactory.getInstance(proxy);
39         service.save();
40     }

  1.3、jdk動態代理和CGLIB區別

    CGLIB是通過字節碼技術,在程序運行時為類創建了一個子類,重寫了父類的方法

      並加入了切面邏輯(無法代理final方法)。

      優點:繼承原對象並重寫方法,所有能代理普通類。

    jdk動態代理是運用jdk反射機制,根據代理類和代理接口生成新的字節碼,然后進行加載並生成

      對象。

      優點:生成代理類相對較快,

      缺點:但是運行切面邏輯沒有CGLIB快,且要實現統一接口擴展性較差。因為要繼承Proxy類

        所以只能代理接口類。

2、IOC

  2.1、控制反轉(獲得依賴對象的方式被反轉)

    在業務中一般都需要至少兩個對象來完成,那么通常情況下每個對象在使用時都需要new,

      這樣就導致對象之間的耦合度高了。IOC的思想就是Spring容器來實現這些相互依賴

    對象的創建、協調,對象只需要關心業務邏輯本身就行了。

    底層原理:反射技術


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM