1. 程式人生 > 實用技巧 >第十八天

第十八天

技術標籤:springjavaaop

淺談AOP和IOC

筆者也是初識Spring,有什麼不對的地方還請斧正!

​ 近來在學習Spring框架,初識框架有點迷惑,所以整理一下目前所學的一些知識吧。

AOPAspect Oriental Program 面向切面程式設計 ,為什麼要先說AOP呢,因為Spring是一個基於AOPIOC的框架。IOC簡單點說就是你以前建立物件都是用new,現在Spring直接承包了,你不用去管如何建立物件了,你直接用就行,就像是去食堂吃飯,廚師大叔們都把菜給你做好了,你只管吃就行了。AOP呢就是一個面向切面的程式設計,注意,切面這個詞很重要,你要理解透了切面的含義對於理解AOP也就沒有多大問題了。

​ 通俗點講AOP的思想就是把功能分成兩大部分,一部分是核心的功能,另一部分是周邊功能(驗證,事務,快取等),然後這個周邊功能叫做切面,他們兩大部分分別獨立的進行開發,你開發你的,我開發我的,到最後將這兩部分進行低耦合的結合,這種思想稱為切面程式設計。這兩部分之間耦合度很低,他們分別獨立開發互不影響,這是最好的開發模式。在Spring中是通過註解或者是配置檔案來實現兩部分結合的。這個過程很抽象,說白了框架其實就是一種高度整合的抽象。接下來我們舉一個例子來方便理解一下。

​ 首先我要有一個業務類:

public class ProductService {

    public void doSomeService
(){ System.out.println("我這裡是業務類"); } }

​ 然後我還要有一個切面類姑且就用來管理日誌吧:

public class LoggerAspect {

    public void log(){
        System.out.println("我是切面類,我用來管理日誌");
    }
}

​ 再然後就是一個配置檔案,這裡我就不用註解了,用配置檔案的話方便理解:

<!--宣告業務物件-->
<bean name="s" class="cn.spring.ProductService"
> </bean> <!--宣告日誌切面--> <bean id="loggerAspect" class="cn.spring.LoggerAspect"/> <aop:config> <!--切點--> <!--設定好切點 當觸發這個切點的時候就會呼叫輔助功能(切面)中的方法 觸發機制就是當訪問了這個類中的任意一個方法的時候--> <aop:pointcut id="loggerCutpoint" expression="execution(* cn.spring.ProductService.*(..)) "/> <!--切面 log叫通知 some..叫方法--> <aop:aspect id="logAspect" ref="loggerAspect"> <aop:after pointcut-ref="loggerCutpoint" method="log"/> </aop:aspect> </aop:config>

​ 最後就是測試類,得出結論之後我會一一進行講解的:

public class TestSpring {
    public static void main(String[] args ){
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"cn/spring/applicationContext.xml"});

        ProductService s = (ProductService)context.getBean("s");
        s.doSomeService();
    }
}

​ 輸出結果:
在這裡插入圖片描述
接下來我對整個執行過程梳理一遍,一開始先執行的肯定是測試類,在測試類中取出配置檔案中的資訊,然後通過Spring新建一個業務類的物件,ProductService s = (ProductService)context.getBean("s");就是這一句建立了一個業務類的物件,然後呼叫業務類中的方法,在呼叫業務類中的方法的時候相當於在這裡有一個斷點,先不急著去呼叫方法,需要根據配置檔案中描述的進行操作。那麼配置檔案中說的是什麼呢?在配置檔案中一上來先聲明瞭兩個物件<bean name="s" class="cn.spring.ProductService">,還有<bean id="loggerAspect" class="cn.spring.LoggerAspect"/>,然後再進行配置,先宣告切入點,切入點這個概念很重要,有切入點那肯定有與之對應的,在這裡我們就叫他切面<aop:pointcut id="loggerCutpoint" expression="execution(* cn.spring.ProductService.*(..)) "/>,這是設定到的切點,大體意思就是有一個id用來標記這個切入點,然後後面相當於是一個觸發機制,**意思就是說執行了業務類中的任意一個方法的時候我就會觸發切面操作。**那麼切面都做了哪些事情呢?首先它定義了一個id用來標記他,然後他就會ref到切面類中,所謂切面操作其實就是呼叫了一個類的普通方法而已。。。

<!--切面 log叫通知 some..叫方法-->
<aop:aspect id="logAspect" ref="loggerAspect">
    <aop:after pointcut-ref="loggerCutpoint" method="log"/>
</aop:aspect>

這個通知是有很多型別的,你可以改成想這樣<aop:before pointcut-ref="loggerCutpoint" method="log"/>,同學們看出去別來了嗎,其實就是一個誰先呼叫的問題,這個如果用註解的話也是有相應的註解的,如@Before(value = "execution(* cn.spring.ProductService.*(..))")

一共有五種型別:

  • Before——在方法呼叫之前呼叫通知

  • After——在方法完成之後呼叫通知,無論方法執行成功與否

  • After-returning——在方法執行成功之後呼叫通知

  • After-throwing——在方法丟擲異常後進行通知

  • Around——通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為

    最後一個我的理解就是這個方法可以被包裹進去,在通知裡面也可以呼叫方法。

參考文獻
https://www.cnblogs.com/mxck/p/7027912.html?utm_source=itdadao&utm_medium=referral
https://blog.csdn.net/yanquan345/article/details/19760027?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control
https://how2j.cn/k/spring/spring-injection/88.html#step215