1、AOP概念:java
面向切面編程(Aspect Oriented Programming)能夠經過預編譯方式和運行期動態代理實如今不修改源代碼的狀況下給程序動態統一添加功能的一種技術。能夠說是OOP(面向對象編程)的補充和完善。spring
如下是AOP的幾個概念:express
一、切面(Aspect ):簡單的理解就是把那些與核心業務無關的代碼提取出來,進行封裝成一個或幾個模塊用來處理那些附加的功能代碼,如日誌、事物、安全驗證。咱們把這個模塊的做用理解爲一個切面,其實切面就是咱們寫的一個類,這個類中的代碼原來是在業務模塊完成的,如今單獨成一個或幾個類。在業務模塊須要的時候才織入。編程
二、鏈接點(Joinpoint):在程序執行過程當中某個特定的點,好比某方法調用的時候或者處理異常的時候。在Spring AOP中,一個鏈接點老是表明一個方法的執行。經過聲明一個JoinPoint類型的參數可使通知(Active)的主體部分得到鏈接點信息。安全
三、切入點(PointCut):本質上是一個鏈接點的結構。在AOP中,能夠定義一個PointCut來捕獲相關方法的調用。app
四、織入(Weaving):把切面(aspect)鏈接到其餘的運用類型或者對象上,並建立一個被通知(advice)的對象。這些能夠在編譯時(如使用AspectJ編譯器)、類加載時和運行時完成。Spring和其餘純Java AOP框架同樣,在運行時完成織入。框架
五、通知(Advice):在切面某個特定的鏈接點上執行的動做。通知有各類類型,其中包括around、before和after等通知。通知的類型將在後面部分進行討論。許多AOP框架,包括Spring,都是以攔截器作通知模型,並維護一個鏈接點爲中心鏈接鏈。函數
通知的類型:學習
(1) 、前置通知:在某鏈接點以前執行的通知,但這個通知不能阻止鏈接點前的執行(除非它拋出一個異常);測試
(2) 、返回通知:在某鏈接點正常完成後執行的通知,例如,一個方法沒有任何拋出,正常返回。
(3) 、拋出異常後通知:在方法拋出異常退出時執行的通知。
(4) 、環繞通知:包括一個鏈接點的通知,如方法調用。這是最強大的一種通知類型。環繞通知能夠在方法調用先後完成自定義的行爲。它也會執行是否繼續執行鏈接點或直接返回它們本身的值或拋出異常來結束執行。
1、編寫一個類封裝用戶的常見操做(UserDao.java)。
package test4.aop;
//封裝用戶常見的操做類
public class UserDao {
public void save(String name){
System.out.println("-----save user----");
}
public void delete(){
System.out.println("----delete user---");
}
public void update(){
System.out.println("----update user---");
}
}
2、編寫一個檢查用戶是否合法的類。
package test4.aop;
//檢查用戶是否合法的類
public class CheckSecurity {
public void check(){
System.out.println("----check admin----");
}
}
3、改寫Spring配置文件實現AOP(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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx " http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 如下是實現AOP面向切面編程的配置 -->
<bean id="checkbean" class="test4.aop.CheckSecurity"></bean>
<bean id="userDao" class="test4.aop.UserDao"/>
<aop:config>
<!-- 建立一個切面Aspect引用了bean "checkbean" -->
<aop:aspect id="security" ref="checkbean">
<!-- 聲明一個切入點 當調用以public 聲明的全部函數時 -->
<!--execution(public * *(..))表達式*以前必須有一個空格-->
<aop:pointcut id="allAddMethod" expression="execution(public * *(..))"/>
<!-- 當執行到切入點時,會在執行切入點以前調用bean "checkbean"中"check"函數 -->
<aop:before method="check" pointcut-ref="allAddMethod"/>
</aop:aspect>
</aop:config>
</beans>
4、編寫測試類:
package test4;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test4.aop.UserDao;
public class Test {
//測試面向切面編程
@SuppressWarnings("resource")
public static void main(String[] args) {
/**讀取Spring配置文件,建立一個bean工廠**/
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = (UserDao)factory.getBean("userDao");
dao.save("zhou");
}
}
總結:在學習書本知識的時候,發現書中的表達式是錯誤的,通過度量找到關於切入點語法定義,解決了問題。
參考:https://blog.csdn.net/corbin_zhang/article/details/80576809
注意:applicationContext.xml的文件頭須要更新,因此文中寫了全部的信息。