Spring學習01--初學者關於AOP和DI的理解

hyf9457發表於2019-01-06

依賴注入DI

Spring通過應用上下文Application Context裝載bean的定義並把他們組裝起來

	例如:knight.xml中的bean是通過XML來進行配置,可以選擇*ClassPathXMLApplicationContext*作為應用上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/knight.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();

上述過程中,通過knight完成embarkOnQuest方法,但該類完全不知道knight這個bean物件具體對應的類是哪個,也不知道embarkOnQuest方法具體執行了什麼。從而實現了程式的鬆耦合,該方式即依賴注入DI。
AOP:面向切面程式設計,可理解為覆蓋在多個元件上的外殼,與核心業務無關的通用服務以宣告的方式靈活地應用到系統中,核心應用甚至感覺不到它的存在。
優點:提高了核心程式碼的內聚,符合面向對面程式設計的思想
如建立一個吟遊詩人類來記錄騎士相關探險故事

public class Minsterl(){
	private PrintStream stream;
	punlic Minsterl(){
	this.stream = stream;
}
	public void singBeforeQuest(){
	stream.println("騎士開始冒險");
}
	public void singAfterQuest(){
	stream.println("騎士冒險結束");
}
}

可以看到 吟遊詩人 Minster 只是一個簡單的POJO類,如下兩種方式實現騎士冒險前後進行傳頌。

public class BraveKnight implents Knight(){
	private Quest quest;
	private Minsterl minsterl;
	public BraveKnight(Quest quest,Minsterl minsterl){
		this.quest = quest;
		this.minsterl = minsterl;
	}
	public void embarkOnQuest(){
	minsterl.singBeforeQuest();
	quest.embark();
	minsterl.singAfterQuest();
}
}

上面的程式碼實現了 在knight執行embarkOnQuest任務的前後吟遊詩人minster記錄了騎士冒險的前後,但knight的任務就是embarOnQuest,吟遊詩人的記錄動作是否需要其來管理呢,是不是執行任務前還有校驗吟遊詩人是否存在,這就使程式碼變得複雜化。而AOP就是專門用來解決這個問題的。
在kngiht.xml中加入如下配置:

<bean id="minstrel" class="xxxx.Minstrel">
	<constructor-arg value="#(T(System).out)"/>
</bean>
<aop:config>
	<aop:aspect ref="minstrel">
		<aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(...))"/>
		<aop:before pointcut-ref="embark" method="singBeforeQuest"/>
		<aop:after pointcut-after="embark" method="singAfterQust"/>
	</aop:aspect>
</aop:config>

上訴配置首先將Minstrel 宣告為一個bean物件minstrel,然後通過<aop:aspect ref=“minstrel”>將該bean物件定義為一個切面,切點位置<aop:pointcut id=“embark” expression=“execution(* *.embarkOnQuest(…))”/>為BraveKnight的embarkOnQuest方法,然後宣告<aop:before pointcut-ref=“embark” mehtod=“singBeforeQuest”>在呼叫embarkOnQuest
方法之前執行singBeforeQuest方法,再由<aop:after pointcut-ref=“embark” mehtod=“singAfterQuest”>宣告embarkOnQuest執行完畢後呼叫singAfterQuest方法。
可以看到,通過AOP,實現了核心業務邏輯與通用服務的分離,實現了降耦。

相關文章