Spring-AOP @AspectJ進階之繫結丟擲的異常
阿新 • • 發佈:2019-01-11
概述
和通過切點函式繫結連線點資訊不同,連線點丟擲的異常必須使用AfterThrowing註解的throwing成員進行繫結
例項
業務類
package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.springframework.stereotype.Component;
@Component
public class BussinessException {
public void dealBussiness(String bussinessName) {
System.out.println("dealBussiness executed" );
// just a demo code ,in fact it's not cautious
if (bussinessName != null && "bug".equals(bussinessName))
throw new IllegalArgumentException("iae Exception");
else
throw new RuntimeException("re Exception");
}
}
切面
package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
/**
*
*
* @ClassName: BindReturnValueAspect
*
* @Description: @Aspect標註的切面,
* 和通過切點函式繫結連線點資訊不同,連線點丟擲的異常必須使用AfterThrowing註解的throwing成員進行繫結
*
* (1)處throwing指定的異常名和(2)處入參的異常名相同,這個異常增強只在連線點丟擲的異常instanceof
* IllegalArgumentException才匹配,增強方法通過iae引數可以訪問丟擲的異常物件。
*
* @author : Mr.Yang
*
* @date: 2017年9月12日 下午5:47:23
*/
@Aspect
public class BindExceptionAspect {
// (1)
@AfterThrowing(value = "target(com.xgj.aop.spring.advisor.aspectJAdvance.bindException.BussinessException)", throwing = "iae")
public void crossCuttingCode(IllegalArgumentException iae) {// (2)
System.out.println("----bindException()----");
System.out.println("exception:" + iae.getMessage());
System.out.println("----bindException()----");
}
}
(1)處throwing指定的異常名和(2)處入參的異常名相同,這個異常增強只在連線點丟擲的異常instanceof IllegalArgumentException才匹配,增強方法通過iae引數可以訪問丟擲的異常物件。
配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- (1)宣告Context名稱空間以及Schema檔案 (2)掃描類包以及應用註解定義的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.bindException"/>
<!-- 基於@AspectJ切面的驅動器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 使用了@AspectJ註解的切面類 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.bindException.BindExceptionAspect"/>
</beans>
單元測試
package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BindExceptionAspectTest {
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:com/xgj/aop/spring/advisor/aspectJAdvance/bindException/conf-bindException.xml");
ctx.getBean("bussinessException", BussinessException.class)
.dealBussiness("bug");
}
}
輸出結果
2017-09-12 20:26:25,344 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3695de1a: startup date [Tue Sep 12 20:26:25 BOT 2017]; root of context hierarchy
2017-09-12 20:26:25,458 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/bindException/conf-bindException.xml]
dealBussiness executed
----bindException()----
exception:iae Exception
----bindException()----
可見當sdealBussiness(“bug”)丟擲異常後,異常增強起效,處理完成後,再向外丟擲IllegalArgumentException。如果將①處的程式碼調整為dealBussiness(“bug2”)後,再執行程式碼,將只看到異常輸出的資訊,異常增強沒有任何動作,這是因為RuntimeException 不按型別匹配於 IllegalArgumentException,切點不匹配。
總結
通過切點複合運算,你可以定義出各種複雜的切點,使切點表示式的能力進一步提升。
你可以直接使用切點複合運算子對切點函式進行運算,也可以通過切點名引用其它命名切點。
當對同一個連線點織入多個增強時,你必須考慮讓切面類實現Ordered介面,此外還必須合理計劃同一個切面類中增強方法的宣告順序,因為這些資訊都會影響到增強的織入順序。
在@AspectJ的切點表示式中,大多數的切點函式都可以繫結連線點方法的入參,以便增強方法訪問連線點資訊。
此外,你也可以簡單地將增強方法的第一個入參定義為JoinPoint訪問連線點的上下文。