I believe that your expectation is incorrect (that only one interception method will correspond similarly to method overloading).
But while RuntimeException is the parent of a DataAccessException , both methods are executed ...
spring.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" 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/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <context:component-scan base-package="test" /> <aop:aspectj-autoproxy /> </beans>
Aoptest
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopTest { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring.xml"); MyService ms = ac.getBean(MyService.class); try { ms.throw1(); } catch (Exception e) {
Myspect
package test; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @Aspect @Component public class MyAspect { @AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex") public void intercept(DataAccessException ex) throws Exception {
MyService
package test; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Service; @Service public class MyService { public void throw1() throws DataAccessException { throw new MyDataAccessException("test"); } public void throw2() { throw new NullPointerException(); } static class MyDataAccessException extends DataAccessException { public MyDataAccessException(String msg) { super(msg); } } }
and in the magazine:
DAE RE - class test.MyService$MyDataAccessException RE - class java.lang.NullPointerException
Maven Dependencies:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.2.4.RELEASE</version> </dependency>
From the Spring documentation :
When two tips defined in the same aspect, both must be executed at the same junction point, the order is undefined (since there is no way to get the declaration order through reflection for javac-compiled classes). Consider folding these tips into one consultation method at each junction point in each aspect class, or reorganizing the tips into separate aspect classes that can be ordered at the aspect level.
When I tried the following modification of MyAspect :
package test; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @Aspect @Component public class MyAspect { @AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex") public void intercept(DataAccessException ex) throws Exception {
log changed to:
DAE RE - class java.lang.IllegalArgumentException RE - class java.lang.NullPointerException
and when changing to Exception I got:
package test; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @Aspect @Component public class MyAspect { @AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex") public void intercept(DataAccessException ex) throws Exception {
the magazine was
DAE RE - class java.lang.NullPointerException
I believe the solution to your โproblemโ is to have two Aspects instead of one and determine the order:
package test; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.Ordered; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @Aspect @Component public class DaeAspect implements Ordered { public int getOrder() { return 200; } @AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex") public void intercept(DataAccessException ex) throws Exception {
and
package test; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.Ordered; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @Aspect @Component public class ReAspect implements Ordered { public int getOrder() { return 100; } @AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex") public void intercept(RuntimeException ex) throws Exception {