1. 程式人生 > >SSM框架專案搭建系列(六)—Spring AOP之基於XML的宣告式AspectJ

SSM框架專案搭建系列(六)—Spring AOP之基於XML的宣告式AspectJ

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();
    }
}

這裡寫圖片描述