今天是五一收假以來的第一天排龄,距離下一周一共還有四天惜互,這周主要是對(duì)Spring的重學(xué)習(xí)吴菠。這四天內(nèi)我將從以下幾個(gè)角度進(jìn)行分析和理解。
(1)AOP的理解和分析
(2)IOC的理解和分析
(3)對(duì)bean的理解和分析
(4)spring配置文件的理解和分析
首先今天對(duì)AOP的理解和分析清寇,對(duì)aop的理解也分開闡述喘漏,對(duì)一個(gè)技術(shù)的思考护蝶,基本上都是從上學(xué)時(shí)候課本闡述一個(gè)新知識(shí)的順序進(jìn)行的。 第一:什么是AOP翩迈?
第二:為什么要引入AOP持灰?或者是AOP解決了什么問題?
第三:如何簡(jiǎn)單的實(shí)現(xiàn)AOP负饲?
第四:AOP對(duì)我們寫代碼時(shí)候的思考和幫助是什么堤魁?
現(xiàn)在,開始對(duì)AOP進(jìn)行闡述绽族,
1 什么是AOP姨涡?
1.1 概念介紹
Spring的使命是簡(jiǎn)化Java代碼開發(fā)衩藤,aop作為Spring的一個(gè)子模塊吧慢,也不例外。
AOP 是 Aspect Oriented Programming(面向切面編程) 的簡(jiǎn)稱赏表,和OOP(面向?qū)ο缶幊蹋┮粯邮且环N編程思想检诗,是對(duì)OOP的一種補(bǔ)充。
如何理解什么是AOP呢瓢剿?以日志為例逢慌,在很多管理系統(tǒng),比如訂單系統(tǒng)间狂、推送系統(tǒng)等等都需要把日志記錄下來攻泼。如果每個(gè)業(yè)務(wù)邏輯里面都寫日志的相關(guān)代碼,那就重復(fù)太多了鉴象。
干脆把日志的相關(guān)邏輯代碼忙菠,統(tǒng)一封裝起來。然后在需要的地方嵌入即可纺弊。AOP也主要就是做嵌入這件事的牛欢。看下面這張圖淆游。
新增訂單編輯訂單取消訂單推送訂單日志事務(wù)
AOP旨在將橫切關(guān)注點(diǎn)(crosscutting concern)從業(yè)務(wù)主體邏輯中進(jìn)行剝離傍睹,實(shí)現(xiàn)關(guān)注點(diǎn)分離,以提高程序的模塊化程度(及業(yè)務(wù)模塊只需關(guān)注業(yè)務(wù)邏輯犹菱,無需關(guān)注日志拾稳、安全、事務(wù)等通用邏輯)
上面提到了一些名詞腊脱,比如說访得,切面、關(guān)注點(diǎn)虑椎、橫切等震鹉,下面對(duì)這些名詞進(jìn)行解釋俱笛。
1.2 名詞解釋
-
AOP有自己的一套術(shù)語,我們必須了解一下這些行話传趾,才能更好地理解AOP迎膜。為了方便大家理解,下面將用課代表收作業(yè)作為例子浆兰。
-
通知 (Advice)
定義了在收作業(yè)前后需要做的事磕仅。常見的通知類型有:before、after簸呈、after-returning榕订、around等。
-
連接點(diǎn) (JoinPoint)
連接點(diǎn)指程序運(yùn)行時(shí)允許插入切面的一個(gè)點(diǎn)蜕便,可以是一個(gè)函數(shù)劫恒、一個(gè)包路徑、一個(gè)類轿腺、或者拋出的異常两嘴。有點(diǎn)類似于可以收作業(yè)的時(shí)間點(diǎn)。
-
切點(diǎn)(PointCut)
切點(diǎn)用于定義切面的位置族壳,也就是捕獲哪些連接點(diǎn)的調(diào)用然后執(zhí)行"通知"的操作(什么地點(diǎn))憔辫。
-
切面(Aspect)
切面是切點(diǎn)和通知的聚合,定義了在哪一個(gè)切點(diǎn)做什么通知仿荆。
-
目標(biāo)對(duì)象( Target )
指被切面織入的對(duì)象贰您。
-
引入(Introduction)
引入允許我們向現(xiàn)有的類添加新方法或?qū)傩浴?/p>
-
織入(Weaving)
織入是把切面應(yīng)用到切點(diǎn)對(duì)應(yīng)的連接點(diǎn)的過程。切面在指定連接點(diǎn)被織入到目標(biāo)對(duì)象中拢操。
-
具體關(guān)系使用圖形化表示是:
2 為什么要引入AOP锦亦?
上面是定義,引入AOP的原因肯定是可以解決目前開發(fā)中存在的某些痛點(diǎn):
(1)目前的開發(fā)當(dāng)中庐冯,相互之間都是模塊化開發(fā)孽亲,使用AOP可以有效的實(shí)現(xiàn)模塊化的思路。
(2)將輔助邏輯(日志展父、安全返劲、監(jiān)控等)從業(yè)務(wù)主體邏輯中進(jìn)行剝離,同步進(jìn)行開發(fā)栖茉。
AOP是一種思想篮绿,這種思想是把一些業(yè)務(wù)邏輯剝離開,然后按照主業(yè)務(wù)邏輯進(jìn)行組合吕漂,最后達(dá)到想要的功能邏輯亲配。
3 如何簡(jiǎn)單的實(shí)現(xiàn)AOP?
3.1 AOP編程思路
本圖是一個(gè)簡(jiǎn)單的思路。
明確需求創(chuàng)建切面類定義切點(diǎn)定義通知思考:要在哪個(gè)方法的什么時(shí)候做什么事(方法前吼虎?方法后犬钢? 還是around ?)即選擇哪個(gè)連接點(diǎn)進(jìn)行執(zhí)行通知在切點(diǎn)附近(before?after?) 做什么操作
下面定義一個(gè)日志的簡(jiǎn)單案例,實(shí)現(xiàn)AOP思灰。使用的是原始的注解方式:
3.2 案例實(shí)現(xiàn)AOP
3.2.1 明確需求
在某個(gè)方法上加上@FddLog玷犹,就會(huì)在執(zhí)行這個(gè)方法的前后,自動(dòng)輸出相應(yīng)的信息洒疚。下面以把大象放進(jìn)冰箱為例子進(jìn)行演示:
3.2.2 基本接口和實(shí)現(xiàn)
public interface ElephentToRe{
public void toRe();
}
實(shí)現(xiàn)類如下:
public class ElephentToReImpl implements ElephentToRe{
public void toRe() {
System.out.println("把大象放冰箱");
}
}
3.2.3 定義切面和通知
public class ElephentToReHelper{
public void beforeElephentToRe(){
System.out.println("把冰箱門打開");
}
public void afterElephentToRe(){
System.out.println("把冰箱門關(guān)上");
}
}
配置就好了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- 定義通知內(nèi)容歹颓,也就是切入點(diǎn)執(zhí)行前后需要做的事情 -->
<bean id="elephentToReHelper" class="com.fdd.bean.ElephentToReHelper"></bean>
<!-- 定義被代理者 -->
<bean id="elephentToReImpl" class="com.fdd.bean.ElephentToReImpl"></bean>
<aop:config>
<aop:aspect ref="elephentToReHelper">
<aop:before method="beforeElephentToRe" pointcut="execution(* *.toRe(..))" />
<aop:after method="afterElephentToRe" pointcut="execution(* *.toRe(..))" />
</aop:aspect>
</aop:config>
</beans>
3.2.4 測(cè)試看效果
public class Test {
public static void main(String[] args){
@SuppressWarnings("resource")
ApplicationContext appCtx = new FileSystemXmlApplicationContext("application.xml");
ElephentToRe elephentToReImpl = (ElephentToRe)appCtx.getBean("elephentToReImpl");
elephentToReImpl.toRe();
}
}
上面的這種方法是通過純粹的POJO切面來完成的。實(shí)現(xiàn)方式也比較簡(jiǎn)單油湖。
4 我對(duì)AOP思想的看法
任何新技術(shù)的出現(xiàn)都是為了解決目前開發(fā)中存在的某些痛點(diǎn)巍扛。對(duì)于aop來說,其主要是把一些功能代碼進(jìn)行抽象封裝乏德,和主業(yè)務(wù)邏輯代碼進(jìn)行剝離撤奸。在需要的地方進(jìn)行織入即可。
我的看法是
(1)在平時(shí)開發(fā)代碼的時(shí)候鹅经,完全可以把一些常見的寂呛,常用的功能代碼進(jìn)行封裝怎诫,盡量做到動(dòng)態(tài)配置瘾晃。不同的功能模塊只需要進(jìn)行織入即可。
(2)定義業(yè)務(wù)邏輯的模板幻妓,比如說如果要解決某一個(gè)業(yè)務(wù)功能蹦误,如果頁面類似,可以按照基本的框架進(jìn)行組合肉津,然后使用配置平臺(tái)進(jìn)行可控化配置即可强胰。