本文主要是對於spring aop簡單入門做一些介紹,並不深入瞭解,只接觸表面,對一些較複雜的內容也不過多描述。如文中有錯誤之處,望不吝賜教,謝謝~
一、AOP簡介
AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
通俗來說aop就是通過動態代理重用代碼進而降低程序耦合性和提高開發效率的一種技術,並且在程序運行期間,不修改源碼就可對已有方法進行增強。
二、AOP常見概念
- Aspect(切面)
Aspect 聲明類似於 Java 中的類聲明,在 Aspect 中會包含着一些 Pointcut 以及相應的 Advice。 - Joint point(連接點)
指那些被攔截的點,在spring中這些點指的是方法。 - Pointcut(切入點)
表示一組 joint point,這些 joint point 或是通過邏輯關係組合起來,或是通過通配、正則表達式等方式集中起來,它定義了相應的 Advice 將要發生的地方。 - Advice(增強/通知)
Advice 定義了在 Pointcut 裏面定義的程序點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之後還是代替執行的代碼。 - Introduction(引介)
一種特殊的通知,可以在不修改源碼的情況下動態添加一些方法。 - Target(目標對象)
織入 Advice 的目標對象.。 - Weaving(織入)
將 Aspect 和其他對象連接起來, 並創建 Adviced object 的過程
三、AOP的簡單實例
(1)新建maven項目
(2)導入ioc和配置切入點表達式(本例中即爲業務層方法)依賴
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
(3)新建業務層接口及實現類,以及日誌類
IUserService.java
package com.example.service;
public interface IUserService {
/**
* 模擬保存用戶
*/
public void saveUser();
/**
* 模擬修改用戶名
* @param username
*/
public void updateUser(String username);
/**
* 模擬刪除用戶
*/
public void deleteUser();
}
UserServiceImpl.java
package com.example.service.impl;
import com.example.service.IUserService;
public class UserServiceImpl implements IUserService {
/**
* 模擬保存用戶
*/
public void saveUser() {
System.out.println("保存用戶");
}
/**
* 模擬修改用戶名
*
* @param username
*/
public void updateUser(String username) {
System.out.println("修改用戶名");
}
/**
* 模擬刪除用戶
*/
public void deleteUser() {
System.out.println("刪除用戶");
}
}
Logger.java
package com.example.utils;
public class Logger {
/**
* 模擬打印日誌,在切入點方法(本例爲業務層方法)執行之前執行
*/
public void printLog(){
System.out.println("打印日誌");
}
}
(4)在resources目錄下創建bean的配置文件bean.xml(在裏面配置ioc和aop相關內容)
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置ioc-->
<bean id="userService" class="com.example.service.impl.UserServiceImpl"/>
<bean id="logger" class="com.example.utils.Logger"/>
<!--配置aop-->
<aop:config>
<!--配置切面 id提供唯一標識 ref指定某一bean-->
<aop:aspect id="logAdvice" ref="logger">
<!--配置前置通知 由於本例是打印日誌的方法在業務層方法前面,所以用前置通知-->
<!--pointcut指定切入點表達式,用以對業務層的哪些方法增強-->
<aop:before method="printLog"
pointcut="execution(public void com.example.service.impl.UserServiceImpl.saveUser())"/>
</aop:aspect>
</aop:config>
</beans>
在上面指定切入點方法時,只指定了一個方法即saveUser(),如果要指定多個方法可使用通配符:* ….*(參數列表)
<aop:before method="printLog"
pointcut="execution(* *..*.*())"/>
(5)新建測試類AopTest,測試AOP使用是否成功
package com.example;
import com.example.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
public static void main(String[] args) {
//獲取ioc容器
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//獲取bean
IUserService userService= (IUserService) ac.getBean("userService");
//測試
userService.saveUser();
}
}
執行main()函數,結果如下
可以看到打印日誌的方法在業務層方法前面執行,測試成功。
四、總結
aop的內容十分繁雜,對於初學者而言,可以先簡單理解爲代碼複用的一種技術。
使用aop的關鍵是其配置文件:
<!--配置aop aop配置在config標籤下-->
<aop:config>
<!--配置切面在aspect標籤下面 id提供唯一標識 ref指定某一bean-->
<aop:aspect id="" ref="">
<!--method爲通知方法 -->
<!--pointcut指定切入點表達式,用以對業務層的哪些方法增強-->
<aop:before method=""
pointcut=""/>
<!--通配寫法 * *..*.*()-->
<!--全通配 * *..*.*(..)-->
<!--一般 * 包名.*.*(..)-->
</aop:aspect>
</aop:config>
注意aop與ioc的聯合使用。
2020.03.21