AOP基本概念、AOP底层实现原理、AOP经典应用【事务管理、异常日志处理、方法审计】...
?
1 什么是AOP
AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
?
2 通過配置實現AOP編程
2.1 導包
2.2 編寫切面類(其實就是一個類)
1 package cn.xiangxu.cloudNote.aspect; 2 3 public class AspectDemo01 { 4 public void logController() { 5 System.out.println("AOP功能注入Controller"); 6 } 7 } View Code2.3 配置切面組件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 6 xmlns:jee="http://www.springframework.org/schema/jee" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:aop="http://www.springframework.org/schema/aop" 9 xmlns:mvc="http://www.springframework.org/schema/mvc" 10 xmlns:util="http://www.springframework.org/schema/util" 11 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 12 xsi:schemaLocation=" 13 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 14 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 15 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 16 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 17 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 18 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 19 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 20 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 21 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> 22 23 <!-- 案例:將AspectDemo01組件的logController方法作用與controller包及其自爆中所有方法 --> 24 <!-- 配置切入功能類的bean組件 --> 25 <bean id="aspectDemo01" class="cn.xiangxu.cloudNote.aspect.AspectDemo01"></bean> 26 <!-- AOP配置 --> 27 <aop:config> 28 <!-- 指定切面組件,通過ref屬性進行關聯 --> 29 <aop:aspect ref="aspectDemo01"> 30 <!-- 通過method指定處理方法 --> 31 <!-- 通過poincut指定切入點 --> 32 <!-- within為類限定表達式 --> 33 <aop:before method="logController" pointcut="within(cn.xiangxu.cloudNote.controller..*)"></aop:before> 34 </aop:aspect> 35 </aop:config> 36 37 </beans> View Code?
3 通過注解實現AOP編程
? 3.1 導包
3.2 創建切面類(在類中添加相關注解)
1 package cn.xiangxu.cloudNote.aspect; 2 3 import org.aspectj.lang.annotation.AfterReturning; 4 import org.aspectj.lang.annotation.Aspect; 5 import org.aspectj.lang.annotation.Before; 6 import org.springframework.stereotype.Component; 7 8 @Component 9 @Aspect 10 public class AspectDemo02 { 11 // @Before(value = "within(cn.xiangxu.cloudNote.service..*)") // service包及其子包中的所有方法 12 // @Before(value = "within(cn.xiangxu.cloudNote.service.*)") // service中的所有方法(子包中的除外) 13 @Before(value = "within(cn.xiangxu.cloudNote.service.NoteServiceImpl)") // NoteServiceImpl類中的所有方法 14 15 public void serviceAspect() { 16 System.out.println("給筆記相關的業務實現類添加切面"); 17 } 18 19 // @Before("execution(* cn.xiangxu.cloudNote.service..*.*(..))") // service包及其子包下的所有方法(方法的返回值和參數沒有限制) 20 @Before("execution(* cn.xiangxu.cloudNote.service.ShareSerive.shareNote(String))") // 指定方法名以及參數 21 public void shareAspect() { 22 System.out.println("給分享筆記方法添加切面"); 23 } 24 25 @Before("bean(*Dao)") 26 public void daoAspect() { 27 System.out.println("給所有持久層方法添加切面"); 28 } 29 30 } View Code@Component 代替在配置文件中配置bean
@Aspect 說明該類中的代碼是一個切面的組件;等價于在配置文件中配置指定切面組件 <aop:aspect ref="loggerBean">
@Before(value = "within(cn.xiangxu.cloudnote.service..*)") 代替在配置文件中配置通知和切入點配置
3.3 在配置文件中配置注解掃描和啟動AOP注解
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 6 xmlns:jee="http://www.springframework.org/schema/jee" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:aop="http://www.springframework.org/schema/aop" 9 xmlns:mvc="http://www.springframework.org/schema/mvc" 10 xmlns:util="http://www.springframework.org/schema/util" 11 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 12 xsi:schemaLocation=" 13 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 14 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 15 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 16 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 17 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 18 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 19 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 20 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 21 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> 22 23 <!-- 掃描組件 --> 24 <context:component-scan base-package="cn.xiangxu.cloudNote.aspect"></context:component-scan> 25 <!-- 啟動aop注解 --> 26 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 27 28 </beans> View Code?
4 AOP編程三要素
切面:追加啥? 就是追加我們單獨封裝的切面代碼
通知:啥時候切入? (前置/后置/異常/最終/環繞)
切入點:切誰? (三種表達式:方法/類型/Bean限定表達式)
4.1 切面(Aspect)
指的是封裝了共同處理的組件,即切面代碼
4.2 通知(Before/AfterReturning/AfterThrowing/After/Around)
就是指定且面兒在哪里執行
1 try{ 2 前置通知(@Before) 3 //執行組件方法 4 后置通知(@AfterReturning) 5 }catch{ 6 異常通知(@AfterThrowing) 7 }finally{ 8 最終通知(@After) 9 } 10 環繞通知(@Around) View Code4.3 切入點
4.3.1 切入點 Pointcut
用于指定目標方法 ,利用配置文件配置的寫法為:pointcut="within(cn.xiangxu.cloudnote.controller..*)
如果利用注解的方式進行AOP編程,那么就會將切入點用表達式來代替并且寫入通知中
4.3.2 表達式
4.3.2.1 方法限定表達式 execution
為某個組件的部分方法追加功能
execution(【修飾符】 返回類型 方法名(參數列表)) 【拋出異常】
execution(* add*(..))
匹配的是所有以add開頭的方法,方法的返回值和參數可以是任意
execution(* cn.xiangxu.cloudnote.service.UserService.*(..))
匹配的是在UserService組件下的所有方法,方法的返回值和參數可以是任意
execution(* cn.xiangxu.cloudnote.service.*.*(..))
匹配的是service下所有組件的所有方法
execution(* cn.xiangxu.cloudnote.service..*.*(..))
匹配的是service包以及子包下所有組件的所有方法s
4.3.2.2 類限定表達式 within
within(cn.xiangxu.cloudnote.service.UserService)
匹配UserService組件下的所有方法
within(cn.xiangxu.cloudnote.service.*)
匹配service包下所有類的所有方法
within(cn.xiangxu.cloudnote.service..*)
匹配到service包及子包下的所有類的所有方法
4.3.2.3?bean限定表達式 bean(id名)
bean(userService)
匹配userService組件的所有方法
bean(*Service)
匹配以Service結尾的組件的所有方法
例子
@Before("bean(userController)")
?
5 AOP實現原理
動態代理
AOP底層實現是通過動態代理技術實現的
動態代理技術:動態創建類的技術
兩種動態代理技術:
基于接口的(java.reflect.Proxy):實現接口,重寫了接口中的方法
public class $Proxy23 implements UserService {
事務處理 + login()處理
將事務處理和login()處理整合到login()方法中
}
通過動態代理創建了一個新的類型
基于類的(CGLIB包):繼承類,重寫類中的方法
?
6 AOP經典應用
事務管理
方法審計
異常日志處理
6.1 案例:實現性能審計
切面:輸出消耗時間
切入點:service下的所有方法
通知:環繞(@Around)
6.2 案例:異常信息寫入日志
要求:當service處理發生異常的時候,將異常信息寫入文件中(利用AOP實現)
切面:將異常信息寫入文件(FileWriter--PrintWriter)
切入點:service下的所有方法
通知:異常(@AfterThrowing)
? 6.3 事務管理
6.3.1?事務
程序為了保證業務處理的完整性,執行的一條或者多條SQL語句
6.3.2?事務管理
對事務中的SQL語句進行提交或者回滾
6.3.3 為什么要使用事務管理
確保數據庫的完整性,不出現臟數據
6.3.4 事務回顧
oracle:commit/rollback (DML操作)
jdbc:默認是自動commit
6.3.5 怎么使用事務管理
》編程式事務管理
利用jdbc連接數據庫就是使用的編程式事務管理
1 try{ 2 業務SQL01 3 業務SQL02 4 業務SQL03 5 conn.commit(); 6 }catch(Exception e) { 7 conn.rollback(); 8 } View Code》聲明式事務管理
》》在配置文件中配置spring事務管理
》》》定義事務管理的bean
org.springframework.jdbc.datasource.DataSourceTransactionManager
》》》開啟注解
@Transactional
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 6 xmlns:jee="http://www.springframework.org/schema/jee" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:aop="http://www.springframework.org/schema/aop" 9 xmlns:mvc="http://www.springframework.org/schema/mvc" 10 xmlns:util="http://www.springframework.org/schema/util" 11 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 12 xsi:schemaLocation=" 13 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 14 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 15 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 16 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 17 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 18 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 19 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 20 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 21 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> 22 23 <!-- Spring 事務處理 --> 24 <!-- 定義事務管理的Bean --> 25 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 26 <property name="dataSource" ref="dbcp"></property> 27 </bean> 28 <!-- 開啟@Transactional --> 29 <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven> 30 31 </beans> View Code》》使用注解標記@Transactional (加到類上就表示對所有的方法都進行事務管理,加到方法上就表示只對該方法進行事務管理)
6.3.6 @Transactional新特性
1 @Transactional標記的特性 2 可讀可寫:readOnly 3 作用于select語句的事務上 4 語法 5 @Transactional(readOnly=true) 6 回滾特性:rollBackFor 7 用于指定回滾的異常類型,因為默認只對運行異常進行處理 8 語法 9 @Transactional(rollBackFor=異常類型) 10 傳播特性 11 @Transactional 12 public void fn1() { 13 業務1處理 14 fn2() // 如果fn2()出現錯誤,就會對業務1進行回滾 15 業務2處理 16 } 17 18 @Transactional 19 public void fn2() { 20 業務3處理 21 } 22 23 隔離特性 24 為解決并發訪問數據庫問題而設計的 25 臟讀:事務一進行了增刪改操作,但并未提交;此時事務二讀取了事務操作的數據;此時, 26 事務一進行了回滾,那么我們就說事務二進行了一次臟讀操作 27 幻讀:事務一在一定范圍內查詢數據,同時事務二在該范圍內又增加了數據,這種現象我們 28 就說事務一做了一次幻讀 View Code?
轉載于:https://www.cnblogs.com/NeverCtrl-C/p/7064435.html
總結
以上是生活随笔為你收集整理的AOP基本概念、AOP底层实现原理、AOP经典应用【事务管理、异常日志处理、方法审计】...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj1334[Baltic2008]
- 下一篇: 实现先pop后push的效果,如支付成功