SSM框架專案搭建系列(六)—Spring AOP之基於XML的宣告式AspectJ
阿新 • • 發佈:2019-01-06
AOP通過“橫切”技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,將其命名為Aspect,即切面。
切面就是將那些與業務無關(例如:許可權認證、日誌、事務處理),確為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組間的耦合度,並有利於未來的可操作性和可維護性。
實現AOP的技術分為兩大類,一是採用動態代理技術,利用擷取訊息的方式,對該訊息進行裝飾,以取代原有物件行為的執行;二是採用靜態織入的方式,引入特定的語法建立切面。
- join point(連線點):是程式執行中的一個精確執行點,例如類中的一個方法。
- point cut(切入點):一個捕獲連線點的結構。
- advice(通知):是point cut的執行程式碼,實質性“切面”的具體邏輯。
- aspect(切面):point cut和advice結合起來就是aspect,表示的是物件間橫切的關係。
- introduce(引入):為物件引入附加的方法或屬性,從而達到修改物件結構的目的。
- AOP Proxy(AOP代理):AOP框架建立的物件,這個物件通常可以作為目標物件的替代品,而AOP代理提供比目標物件更為強大的功能。
- Target Object(目標物件):包含一個連線點的物件,也被稱為代理物件。
- Before Advice(前置通知):在某連線點(Join Point)之前執行的通知,但這個通知不能阻止連線點前的執行,ApplicationContext中在< aop:aspect >裡面使用< aop:before >元素進行宣告。
- After Advice(後置通知):當某連線點退出的時候執行的通知。
- After Return Advice(返回後通知):當某連線點退出的時候執行的通知,不包括丟擲異常的情況。
- Around Advice(環繞通知):包含一個連線點的通知,可以在方法呼叫前後完成自定義的行為。
- After throwing advice(丟擲異常後的通知):在方法丟擲異常退出時執行的通知。
下面通過一個例子來說明AOP
dispatcher-servlet.xml web.xml用之前的,不用改,com.ssm下的包也不用管
applicationContext.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--被增強的bean-->
<bean id="person" class="AOP.Person"/>
<!--增強方法的bean-->
<bean id="adivceMethod" class="AOP.AdivceMethod"/>
<aop:config proxy-target-class="true">
<aop:pointcut id="pointcut" expression="execution(* AOP.Person.*(..))"/> <!-- 定義切點 -->
<aop:aspect ref="adivceMethod"> <!-- 定義切面 -->
<aop:before method="beforeEat" pointcut-ref="pointcut"/><!-- 定義前置增強方法 -->
<aop:after method="afterEat" pointcut="execution(* AOP.Person.eatLunch(..))"/> <!--定義後置增強,使用匿名切點 -->
<aop:around method="aroundEat" pointcut="execution(* AOP.Person.eatSupper(..))"/> <!--定義環繞增下強,使用匿名切點 -->
</aop:aspect>
</aop:config>
</beans>
Person.java
package AOP;
/**
* DateTime: 2016/11/2 21:35
* 功能:
* 思路:
*/
public class Person {
public void eatBreakfast(){
System.out.println("......eatBreakfast()早餐......");
}
public void eatLunch(){
System.out.println("......eatLunch()午餐......");
}
public void eatSupper(){
System.out.println("......eatSupper()晚餐......");
}
}
AdivceMethod.java
package AOP;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* DateTime: 2016/11/2 21:40
* 功能:
* 思路:
*/
public class AdivceMethod {
public void beforeEat(){
System.out.println("...吃飯之前洗手...");
}
public void afterEat(){
System.out.println("...吃飯之後洗碗...");
}
public Object aroundEat(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("........吃飯前先逛一逛........");
Object value = proceedingJoinPoint.proceed();
System.out.println("........吃完後要睡覺了........");
return value;
}
}
AopTest.java
package AOP;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* DateTime: 2016/11/2 22:10
* 功能:
* 思路:
*/
public class AopTest {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Person person= (Person) context.getBean("person");
System.out.println();
person.eatBreakfast();
System.out.println();
person.eatLunch();
System.out.println();
person.eatSupper();
System.out.println();
}
}