spring的AOP配置之@注解方式
AOP配置(注解)
spring的AOP概念在spring的AOP配置之XML方式這騙博客中詳細介紹了,這篇博客就直接開始介紹AOP配置需要那些注解
AOP注解詳解
@Aspect 標志為一個切面類
? 名稱:@Aspect
? 類型:注解
? 位置:類定義上方
? 作用:設置當前類為切面類
? 格式:
? 說明:一個beans標簽中可以配置多個aop:config標簽
@Pointcut 使用當前方法名作為切入點引用名稱
? 名稱:@Pointcut
? 類型:注解
? 位置:方法定義上方
? 作用:使用當前方法名作為切入點引用名稱
? 格式:
? 說明:被修飾的方法忽略其業務功能,格式設定為無參無返回值的方法,方法體內空實現(非抽象)
@Before 標注當前方法作為前置通知
? 名稱:@Before
? 類型:注解
? 位置:方法定義上方
? 作用:標注當前方法作為前置通知
? 格式:
? 特殊參數:
◆ 無
@After 標注當前方法作為后置通知
名稱:@After
? 類型:注解
? 位置:方法定義上方
? 作用:標注當前方法作為后置通知
? 格式:
? 特殊參數:
◆ 無
@AfterReturning 標注當前方法執行成功后作為返回后通知
? 名稱:@AfterReturning
? 類型:注解
? 位置:方法定義上方
? 作用:標注當前方法作為返回后通知
? 格式:
? 特殊參數:
◆ returning :設定使用通知方法參數接收返回值的變量名
@AfterThrowing 標注當前方法作為異常后通知
? 名稱:@AfterThrowing
? 類型:注解
? 位置:方法定義上方
? 作用:標注當前方法作為異常后通知
? 格式:
? 特殊參數:
◆ throwing :設定使用通知方法參數接收原始方法中拋出的異常對象名
@Around 標注當前方法作為環繞通知
AOP注解詳解
? 名稱:@Around
? 類型:注解
? 位置:方法定義上方
? 作用:標注當前方法作為環繞通知
? 格式:
? 特殊參數:
◆ 無
@EnableAspectJAutoProxy AOP注解驅動
? 名稱:@EnableAspectJAutoProxy
? 類型:注解
? 位置:Spring注解配置類定義上方
? 作用:設置當前類開啟AOP注解驅動的支持,加載AOP注解
? 格式:
注解開發AOP注意事項
AOP注解代碼實現
圖解AOP從xml轉變為XML
POM
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.9.RELEASE</version></dependency><!-- aop切面包--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>SpringConfig配置類
package com.fs.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; //標志為配置類 @Configuration //掃描那些路徑下的包的類的spring注解 @ComponentScan("com.fs") //開啟AOP注解支持 替換 xml <aop:aspectj-autoproxy/> @EnableAspectJAutoProxy public class SpringConfig { }模擬三層架構的server,動態代理service接口的實現類
AopService接口
package com.fs.service;public interface AopService {void findAll();int add(String str);void findById();void del();void update(); }AopServiceImpl實現類
package com.fs.service.impl;import com.fs.service.AopService; import org.springframework.stereotype.Service;//把業務類交給spring管理 @Service public class AopServiceImpl implements AopService {@Overridepublic void findAll() {System.out.println("業務層執行了findAll~~~");}/**** @param str 傳遞一個參數,在切面類的通知方法中去接收查看* @return 返回一個值,在切面類的通知方法中去接收*/@Overridepublic int add(String str) {System.out.println("業務層執行了add~~~");//返回一個值,在切面類的通知方法中去接收return 54088;}@Overridepublic void findById() {System.out.println("業務層執行了findById~~~");//制造異常來是異常通知生效 // int i = 1/0;}@Overridepublic void del() {System.out.println("業務層執行了del~~~");}@Overridepublic void update() {System.out.println("業務層執行了update~~~");} }@Aspect 切面類
package com.fs.aop;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;import java.util.Arrays;/* 這個類是AOP的切面類里面編輯一些織入的方法*///將這個類交給spring管理 @Component //標志這個類為切面類 @Aspect public class AOPDemoAdvice {//配置切入點,切入這個com.fs.service.AopService.find*(..)方法,因為ioc中存入了實現類,執行切方法的時候會從ioc中獲取實現類@Pointcut("execution(* com.fs.service.AopService.find*(..))")public void pt(){}// @Before("pt()")public void proxyAOPBefore(JoinPoint jp){Object[] args = jp.getArgs();System.out.println("給切入點(方法)添加了前置通知~~~"+".."+ Arrays.toString(args)+"...");}// @After("pt()")public void proxyAOPAfter(){/*這個后置通知是無論代碼是否出現異常,都會執行這個通知*/System.out.println("給切入點(方法)添加了后置通知~~~");}//測試獲取切入點的的參數和返回值//這個注解,可以獲取方法正常執行后,獲取方法的返回值 returning是返回值的名字,自己定義名字 // @AfterReturning(value = "execution(* com.fs.service.impl.*.add(..))",returning = "num")//直接切入點位接口的方法也行.因為我們在ioc中有存入了實現類的@AfterReturning(value = "execution(* com.fs.service.AopService.add(..))",returning = "num")public void proxyAOPAfterReturning(JoinPoint jp,Object num) {/*BeforeReturning表示的是代碼運行成功無任何異常,會執行的通知*///獲取傳遞的參數Object[] args = jp.getArgs();System.out.println("給切入點(方法)添加了代碼運行成功后的后置通知~~~"+".切入點傳遞的參數."+Arrays.toString(args)+".切入點返回的值."+num);}// @AfterThrowing("pt()")public void proxyAOPAfterThrowing() {System.out.println("給切入點(方法)添加了代碼運行異常后的后置通知~~~");}/*環繞通知環繞通知可以將上面的通知方法全部實現ProceedingJoinPoint這類就代表切入點,可以給這個切入點執行配置通知*/@Around("pt()") // @Around("execution(* com.fs.service.impl.*.find*(..))")也可以在后面直接寫切入點的表達式public Object proxyAOPAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {Object proceed = null;try {//proceedingJoinPoint切入點執行前配置前置通知System.out.println("環繞通知的前置通知執行的代碼");//切入點(被動態代理的方法)執行proceed = proceedingJoinPoint.proceed();//proceedingJoinPoint切入點執行成功無報錯后配置前置通知System.out.println("環繞通知的-成功運行-后執行的代碼");} catch (Throwable throwable) {//proceedingJoinPoint切入點執行前配置異常通知System.out.println("環繞通知的切入點執行-異常后-執行的代碼");throwable.printStackTrace();} finally {//proceedingJoinPoint切入點執行前后通知,就是代碼無論是異常,還成功運行,都會執行的增強代碼System.out.println("環繞通知的后置通知執行的代碼");}return proceed;} }測試類
package com.fs.aop;import com.fs.config.SpringConfig; import com.fs.service.AopService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*; //開啟junit的執行器 @RunWith(SpringJUnit4ClassRunner.class) //加載spring的配置類 @ContextConfiguration(classes = SpringConfig.class) public class AopDemoTest {//從ioc中獲取@Autowiredprivate AopService aopService;@Testpublic void method() {//調用方法aopService.findById();// int add = aopService.add("牛批");}}aopService.findById();執行結果
aopService.add(“牛批”);執行結果
AOP注解開發通知執行順序控制(了解)
? AOP使用XML配置情況下,通知的執行順序由配置順序決定,在注解情況下由于不存在配置順序的概念
的概念,參照通知所配置的方法名字符串對應的編碼值順序,可以簡單理解為字母排序
◆ 同一個通知類中,相同通知類型以方法名排序為準
◆ 不同通知類中,以類名排序為準
◆ 使用@Order注解通過變更bean的加載順序改變通知的加載順序
? 企業開發經驗
◆ 通知方法名由3部分組成,分別是前綴、順序編碼、功能描述
◆ 前綴為固定字符串,例如baidu、itheima等,無實際意義
◆ 順序編碼為6位以內的整數,通常3位即可,不足位補0
◆ 功能描述為該方法對應的實際通知功能,例如exception、strLenCheck
◆ 控制通知執行順序使用順序編碼控制,使用時做一定空間預留
? 003使用,006使用,預留001、002、004、005、007、008
? 使用時從中段開始使用,方便后期做前置追加或后置追加
? 最終順序以運行順序為準,以測試結果為準,不以設定規則為準
總結
以上是生活随笔為你收集整理的spring的AOP配置之@注解方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring的AOP配置之XML方式
- 下一篇: spring中AOP动态代理的两种方式