Spring AOP編程
- 什么是 AOP 編程?
AOP是Aspect Oriented Programming的縮寫,意思是面向方面編程,與OOP(Object Oriented Programming)面向?qū)ο缶幊虒Φ?,都是一種編程思想。
從OOP角度分析,我們關(guān)注業(yè)務(wù)的處理邏輯,是屬于縱向的行為,從AOP角度分析,我們關(guān)注對象行為發(fā)生時的問題,是屬于橫向的行為。
- AOP 包括什么?
切面
切入點
通知定義了切面的什么和何時,切點定義了何處,切點的定義會匹配通知所要織入的一個或多個連接點,我們通常使用明確的類的方法名稱來指定這些切點,或是利用正則表達(dá)式定義匹配的類和方法名稱來指定這些切點。
通知
前置通知
后置通知
異常通知
環(huán)繞通知
- AOP 開發(fā)步驟
新建一個切面類,實現(xiàn)通知接口
修改spring 配置文件或使用注解,把切面類交給 spring 進(jìn)行管理
修改 spring 配置文件,引入 aop 名稱空間配置
配置 aop:config
執(zhí)行包含切入點的代碼,切面自動執(zhí)行
1. 新建一個工程,工程結(jié)構(gòu)如下所示:

項目工程結(jié)構(gòu)圖
部分代碼展示(Getting Setting 方法已省略):
Category.java :
package com.neuedu.springaop.bean
public class Category {
private int id;
private String name;
public Category() {
super();
}
public Category(int id) {
super();
this.id = id;
public Category(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
ICategoryDao.java (模擬數(shù)據(jù)庫操作)
package com.neuedu.springaop.dao;
import java.util.List;
import com.neuedu.springaop.bean.Category;
public interface ICategoryDao {
public boolean saveCategory(Category category);
public boolean deleteCategory(Category category);
public boolean editCategory(Category category);
public Category findById(int id);
public List<Category> searchByExample(Category category);
}
ICategoryService.java
package com.neuedu.springaop.service;
import java.util.List;
import com.neuedu.springaop.bean.Category;
public interface ICategoryService {
public boolean saveCategory(Category category);
public boolean deleteCategory(Category category);
public boolean editCategory(Category category);
public Category findById(int id);
public List<Category> searchByExample(Category category);
}
新建一個切面類 : Thranslation.java
package com.neuedu.springaop.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
/*
* 模擬事務(wù)的類
*
* 1.前置通知接口:MethodBeforeAdvice,對應(yīng)切入點-表示在方法調(diào)用前切入
* 2.后置通知接口:AfterReturningAdvice,對應(yīng)切入點-表示在方法返回后執(zhí)行
*/
public class Thranslation implements MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice{
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("模擬事務(wù)開啟......");
}
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("模擬事務(wù)提交......");
}
public void afterThrowing(Exception e) {
System.out.println("模擬事務(wù)回滾......");
}
}
2-4. 修改后的applicationContext.xml 文件內(nèi)容:
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置aop切面 -->
<!-- 把切面類交給spring進(jìn)行管理 -->
<bean id="Thranslation" class="com.neuedu.springaop.aop.Thranslation"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入點 -->
<!-- 切入點表達(dá)式說明:execution表示執(zhí)行,第一個*號表示修飾符號,接著配置package包名.接口名或類名.方法名(參數(shù)列表)
*號表示多種情況,參數(shù)的兩點表示不定參數(shù)(0-n個參數(shù))
-->
<aop:pointcut expression="execution(* com.neuedu.springaop.service.ICategoryService.*(..))
" id="txPointcut"/>
<!-- 配置aop通知 -->
<aop:advisor advice-ref="Thranslation" pointcut-ref="txPointcut"/>
</aop:config>
<!-- 表示層 -->
<!-- 業(yè)務(wù)邏輯層 -->
<bean id="CategoryServiceImpl" class="com.neuedu.springaop.service.impl.CategoryServiceImpl">
<property name="categoryDao" ref="CategoryDaoImpl"></property>
</bean>
<!-- 數(shù)據(jù)訪問層 -->
<bean id="CategoryDaoImpl" class="com.neuedu.springaop.dao.impl.CategoryDaoImpl"></bean>
</beans>
5. 執(zhí)行包含切入點的代碼,切面自動執(zhí)行
編寫一個測試類 TestCategoryService.java
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.neuedu.springaop.bean.Category;
import com.neuedu.springaop.service.ICategoryService;
public class TestCategoryService {
public static void main(String[] args) {
//1.配置spring環(huán)境
String configLocation = "config/applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
//2.獲取業(yè)務(wù)對象
ICategoryService service = context.getBean(ICategoryService.class);
//3.進(jìn)行業(yè)務(wù)測試
Category category = new Category();
boolean res = service.saveCategory(category);
if(res) {
System.out.println("新增成功");
}else {
System.out.println("新增失敗");
}
}
}
執(zhí)行測試程序,獲得執(zhí)行結(jié)果 :
模擬事務(wù)開啟......
執(zhí)行新增功能...
模擬事務(wù)提交......
新增成功