淺談@Aspect@Order各個(gè)通知的執(zhí)行順序
@Aspect@Order各個(gè)通知的執(zhí)行順序
兩個(gè)切面類:【記錄日志】和【判斷參數(shù)】,分別對(duì)應(yīng)順序 @Order(0) 和@Order(1) 。
本文只是將重點(diǎn)說(shuō)下 執(zhí)行順序 這么回事哈哈哈
代碼
【業(yè)務(wù)類】
/** * 登錄控制器 */ @Controller public class LoginController { //向外面拋出異常 public void loginWithThrow(String username, String password) throws Exception { if (username == null || password == null) { throw new Exception("登錄信息不可為空啊"); } System.out.println("LoginController#login..."); } //拋出異常自己捕獲的情況 public void loginWithTryCatch(String username, String password) { try{ if (username == null || password == null) { throw new Exception("登錄信息不可為空啊"); } System.out.println("LoginController#login..."); }catch (Exception e){ e.printStackTrace(); } } }
【切面類】
/** * 輸出日志注解 */ @Order(0) @Aspect @Component public class LogAspect { //抽出共通的execution用的 //com.yuki.demo.aop.aspect 包或者子包下所有類的方法 @Pointcut("execution(* com.yuki.demo.aop.aspect..*.*(..))") public void pointcut(){ } //前置通知 // @Before("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") @Before("pointcut()") public void before() { System.out.println("LogAspect#before..."); } //環(huán)繞通知 //ProceedingJoinPoint 只有環(huán)繞通知有 @Around("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("LogAspectA#around開(kāi)始..."); //代理方法的執(zhí)行,如果沒(méi)有joinPoint.proceed() ,則前置通知@Before 不會(huì)執(zhí)行,其它的通知正常 joinPoint.proceed(); //執(zhí)行方法之后,如果joinPoint.proceed() 拋出了異常,則該句不會(huì)執(zhí)行,拋出異常后直接跳出了aroud方法了 System.out.println("LogAspectA#around結(jié)束..."); } //后置通知(只要連接點(diǎn)被執(zhí)行,不管是否拋出異常) @After("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") public void after() { System.out.println("LogAspect#after..."); } //異常通知(只有在joinPoint.proceed()方法執(zhí)行向外面拋出了異常,才會(huì)執(zhí)行該通知) @AfterThrowing("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") public void afterThrowing() { System.out.println("LogAspect#afterThrowing..."); } //正常的返回通知通知(正常結(jié)束了才會(huì)執(zhí)行該通知) @AfterReturning("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") public void afterReturning() { System.out.println("LogAspect#afterReturning..."); } }
【切面類】
/** * 判斷請(qǐng)求參數(shù)的sign是否正確的 切面類 */ @Order(1) @Aspect @Component public class SignAspect { @Around("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))") public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("SignAspect#around開(kāi)始..."); joinPoint.proceed(); System.out.println("SignAspect#around結(jié)束..."); } }
【啟動(dòng)配置】
省略。。。非重點(diǎn)
【測(cè)試類】
@SpringBootTest class AopApplicationTests { @Autowired private LoginController loginController; @Test void contextLoads() { loginController.loginWithTryCatch("yuki", "1234"); } }
【控制臺(tái)輸出】
LogAspectA#around開(kāi)始...
LogAspect#before...
SignAspect#around開(kāi)始...
LoginController#login...
SignAspect#around結(jié)束...
LogAspectA#around結(jié)束...
LogAspect#after...
LogAspect#afterReturning...
小結(jié)
spring AspectJ order(順序)
@Aspect @Order(2) public class HelloWorldAspectAnnotation { /** * JoinPoint接口 * @param joinPoint */ /*public interface JoinPoint { String toString(); //連接點(diǎn)所在位置的相關(guān)信息 String toShortString(); //連接點(diǎn)所在位置的簡(jiǎn)短相關(guān)信息 String toLongString(); //連接點(diǎn)所在位置的全部相關(guān)信息 Object getThis(); //返回AOP代理對(duì)象 Object getTarget(); //返回目標(biāo)對(duì)象 Object[] getArgs(); //返回被通知方法參數(shù)列表 Signature getSignature(); //返回當(dāng)前連接點(diǎn)簽名 SourceLocation getSourceLocation();//返回連接點(diǎn)方法所在類文件中的位置 String getKind(); //連接點(diǎn)類型 StaticPart getStaticPart(); //返回連接點(diǎn)靜態(tài)部分 }*/ //定義前置通知,注意這里是sayHello2 //使用@Before進(jìn)行前置通知聲明,其中value用于定義切入點(diǎn)表達(dá)式或引用命名切入點(diǎn) @Before(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param") public void beforeAdvice(JoinPoint joinPoint,String param) { System.out.println(1); System.out.println("======================="); System.out.println("===param:" + param); System.out.println("======================="); System.out.println(joinPoint.getArgs().length); System.out.println("======================="); System.out.println(joinPoint.toString()); System.out.println("======================="); System.out.println(joinPoint.getTarget()); System.out.println("======================="); System.out.println(joinPoint.getThis()); System.out.println("======================="); System.out.println("===========before advice"); } /*value:指定切入點(diǎn)表達(dá)式或命名切入點(diǎn); pointcut:同樣是指定切入點(diǎn)表達(dá)式或命名切入點(diǎn),如果指定了將覆蓋value屬性指定的,pointcut具有高優(yōu)先級(jí);*/ @AfterReturning(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param",pointcut="execution(* com.boventech..*.sayHello2(..))&& args(param)") public void afterFinallyAdvice(JoinPoint joinPoint,String param) { System.out.println("param:"+param); System.out.println("==========="); System.out.println("===========after finally advice"); } }
@Aspect @Order(1) public class HelloWorldAspectAnnotation2 { /** * JoinPoint接口 * @param joinPoint */ /*public interface JoinPoint { String toString(); //連接點(diǎn)所在位置的相關(guān)信息 String toShortString(); //連接點(diǎn)所在位置的簡(jiǎn)短相關(guān)信息 String toLongString(); //連接點(diǎn)所在位置的全部相關(guān)信息 Object getThis(); //返回AOP代理對(duì)象 Object getTarget(); //返回目標(biāo)對(duì)象 Object[] getArgs(); //返回被通知方法參數(shù)列表 Signature getSignature(); //返回當(dāng)前連接點(diǎn)簽名 SourceLocation getSourceLocation();//返回連接點(diǎn)方法所在類文件中的位置 String getKind(); //連接點(diǎn)類型 StaticPart getStaticPart(); //返回連接點(diǎn)靜態(tài)部分 }*/ //定義前置通知,注意這里是sayHello2 //使用@Before進(jìn)行前置通知聲明,其中value用于定義切入點(diǎn)表達(dá)式或引用命名切入點(diǎn) @Before(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param") public void beforeAdvice(JoinPoint joinPoint,String param) { System.out.println(2); System.out.println("======================="); } /*value:指定切入點(diǎn)表達(dá)式或命名切入點(diǎn); pointcut:同樣是指定切入點(diǎn)表達(dá)式或命名切入點(diǎn),如果指定了將覆蓋value屬性指定的,pointcut具有高優(yōu)先級(jí);*/ @AfterReturning(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param",pointcut="execution(* com.boventech..*.sayHello2(..))&& args(param)") public void afterFinallyAdvice(JoinPoint joinPoint,String param) { System.out.println("order:" + 2); } }
public class AopAnnotationTest { @Test public void testHelloworld() { ApplicationContext ctx = new ClassPathXmlApplicationContext("/helloWorld2.xml"); IHelloWorld2Service helloworldService =ctx.getBean("helloWorld2Service", IHelloWorld2Service.class); String param = "12"; helloworldService.sayHello2(param); } }
<aop:aspectj-autoproxy/> <bean id="helloWorld2Service" class="com.boventech.learning.serviceImpl.HelloWorld2ServiceImpl"/> <bean id="aspect" class="com.boventech.learning.aspect.HelloWorldAspectAnnotation"/> <bean id="aspect2" class="com.boventech.learning.aspect.HelloWorldAspectAnnotation2"/>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)Excel轉(zhuǎn)換為圖片
在實(shí)際開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)有這樣的需求,需要將Excel表格或特定區(qū)域轉(zhuǎn)換為圖片,所以小編今天就來(lái)為大家介紹一下如何使用Java將Excel轉(zhuǎn)化為圖片吧2023-10-10SpringBoot前后端分離實(shí)現(xiàn)個(gè)人博客系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了使用springboot+mybatis+前端vue,使用前后端分離架構(gòu)實(shí)現(xiàn)的個(gè)人博客系統(tǒng),感興趣的小伙伴可以動(dòng)手嘗試一下2022-06-06Java面向?qū)ο笾甪inal關(guān)鍵字詳細(xì)解讀
這篇文章主要介紹了Java面向?qū)ο笾甪inal關(guān)鍵字詳細(xì)解讀,final修飾的屬性又叫常量,一般用 XX_XX_XX來(lái)命名,final修飾的屬性在定義時(shí)必須賦初始值,并且以后不能再修改,需要的朋友可以參考下2024-01-01Spring Cloud Feign組成配置過(guò)程解析
這篇文章主要介紹了Spring Cloud Feign組成配置過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Spring Security如何基于Authentication獲取用戶信息
這篇文章主要介紹了Spring Security如何基于Authentication獲取用戶信息,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Spring Boot 2 整合 QuartJob 實(shí)現(xiàn)定時(shí)器實(shí)時(shí)管理功能
Quartz是一個(gè)完全由java編寫(xiě)的開(kāi)源作業(yè)調(diào)度框架,形式簡(jiǎn)易,功能強(qiáng)大。接下來(lái)通過(guò)本文給大家分享Spring Boot 2 整合 QuartJob 實(shí)現(xiàn)定時(shí)器實(shí)時(shí)管理功能,感興趣的朋友一起看看吧2019-11-11Java如何實(shí)現(xiàn)URL帶請(qǐng)求參數(shù)(get/post)及得到get和post請(qǐng)求url和參數(shù)列表的方法
本文給大家介紹Java如何實(shí)現(xiàn)URL帶請(qǐng)求參數(shù)(get/post)及得到get和post請(qǐng)求url和參數(shù)列表的方法,涉及到 java獲取post請(qǐng)求參數(shù)的方法,感興趣的朋友一起看看吧2015-10-10使用java實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)
這篇文章主要介紹了使用java實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07