forked from spring-projects/spring-framework
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test status quo for 'after' advice invocation order
- Loading branch information
Showing
5 changed files
with
360 additions
and
25 deletions.
There are no files selected for viewing
107 changes: 107 additions & 0 deletions
107
...t/java/org/springframework/aop/config/AopNamespaceHandlerAdviceOrderIntegrationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Copyright 2002-2020 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.aop.config; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.test.annotation.DirtiesContext; | ||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||
|
||
/** | ||
* Integration tests for advice invocation order for advice configured via the | ||
* AOP namespace. | ||
* | ||
* @author Sam Brannen | ||
* @since 5.0.18 | ||
* @see org.springframework.aop.framework.autoproxy.AspectJAutoProxyAdviceOrderIntegrationTests | ||
*/ | ||
class AopNamespaceHandlerAdviceOrderIntegrationTests { | ||
|
||
@Nested | ||
@SpringJUnitConfig(locations = "AopNamespaceHandlerAdviceOrderIntegrationTests-afterFirst.xml") | ||
@DirtiesContext | ||
class AfterAdviceFirstTests { | ||
|
||
@Test | ||
void afterAdviceIsInvokedFirst(@Autowired Echo echo, @Autowired EchoAspect aspect) throws Exception { | ||
assertThat(aspect.invocations).isEmpty(); | ||
assertThat(echo.echo(42)).isEqualTo(42); | ||
assertThat(aspect.invocations).containsExactly("after", "after returning"); | ||
|
||
aspect.invocations.clear(); | ||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception())); | ||
assertThat(aspect.invocations).containsExactly("after", "after throwing"); | ||
} | ||
} | ||
|
||
@Nested | ||
@SpringJUnitConfig(locations = "AopNamespaceHandlerAdviceOrderIntegrationTests-afterLast.xml") | ||
@DirtiesContext | ||
class AfterAdviceLastTests { | ||
|
||
@Test | ||
void afterAdviceIsInvokedLast(@Autowired Echo echo, @Autowired EchoAspect aspect) throws Exception { | ||
assertThat(aspect.invocations).isEmpty(); | ||
assertThat(echo.echo(42)).isEqualTo(42); | ||
assertThat(aspect.invocations).containsExactly("after returning", "after"); | ||
|
||
aspect.invocations.clear(); | ||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception())); | ||
assertThat(aspect.invocations).containsExactly("after throwing", "after"); | ||
} | ||
} | ||
|
||
|
||
static class Echo { | ||
|
||
Object echo(Object obj) throws Exception { | ||
if (obj instanceof Exception) { | ||
throw (Exception) obj; | ||
} | ||
return obj; | ||
} | ||
} | ||
|
||
static class EchoAspect { | ||
|
||
List<String> invocations = new ArrayList<>(); | ||
|
||
void echo() { | ||
} | ||
|
||
void succeeded() { | ||
invocations.add("after returning"); | ||
} | ||
|
||
void failed() { | ||
invocations.add("after throwing"); | ||
} | ||
|
||
void after() { | ||
invocations.add("after"); | ||
} | ||
} | ||
|
||
} |
186 changes: 186 additions & 0 deletions
186
.../springframework/aop/framework/autoproxy/AspectJAutoProxyAdviceOrderIntegrationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/* | ||
* Copyright 2002-2020 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.aop.framework.autoproxy; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.aspectj.lang.annotation.After; | ||
import org.aspectj.lang.annotation.AfterReturning; | ||
import org.aspectj.lang.annotation.AfterThrowing; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.annotation.Pointcut; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.EnableAspectJAutoProxy; | ||
import org.springframework.test.annotation.DirtiesContext; | ||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||
|
||
/** | ||
* Integration tests for advice invocation order for advice configured via | ||
* AspectJ auto-proxy support. | ||
* | ||
* @author Sam Brannen | ||
* @since 5.0.18 | ||
* @see org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests | ||
*/ | ||
class AspectJAutoProxyAdviceOrderIntegrationTests { | ||
|
||
@Nested | ||
@SpringJUnitConfig(AfterAdviceFirstConfig.class) | ||
@DirtiesContext | ||
class AfterAdviceFirstTests { | ||
|
||
@Test | ||
void afterAdviceIsInvokedFirst(@Autowired Echo echo, @Autowired AfterAdviceFirstAspect aspect) throws Exception { | ||
assertThat(aspect.invocations).isEmpty(); | ||
assertThat(echo.echo(42)).isEqualTo(42); | ||
assertThat(aspect.invocations).containsExactly("after", "after returning"); | ||
|
||
aspect.invocations.clear(); | ||
assertThatExceptionOfType(Exception.class).isThrownBy( | ||
() -> echo.echo(new Exception())); | ||
assertThat(aspect.invocations).containsExactly("after", "after throwing"); | ||
} | ||
} | ||
|
||
|
||
@Nested | ||
@SpringJUnitConfig(AfterAdviceLastConfig.class) | ||
@DirtiesContext | ||
class AfterAdviceLastTests { | ||
|
||
@Test | ||
void afterAdviceIsNotInvokedLast(@Autowired Echo echo, @Autowired AfterAdviceLastAspect aspect) throws Exception { | ||
assertThat(aspect.invocations).isEmpty(); | ||
assertThat(echo.echo(42)).isEqualTo(42); | ||
// On Java versions prior to JDK 7, we would expect the @After advice to be invoked last. | ||
assertThat(aspect.invocations).containsExactly("after", "after returning"); | ||
|
||
aspect.invocations.clear(); | ||
assertThatExceptionOfType(Exception.class).isThrownBy( | ||
() -> echo.echo(new Exception())); | ||
// On Java versions prior to JDK 7, we would expect the @After advice to be invoked last. | ||
assertThat(aspect.invocations).containsExactly("after", "after throwing"); | ||
} | ||
} | ||
|
||
|
||
@Configuration | ||
@EnableAspectJAutoProxy(proxyTargetClass = true) | ||
static class AfterAdviceFirstConfig { | ||
|
||
@Bean | ||
AfterAdviceFirstAspect echoAspect() { | ||
return new AfterAdviceFirstAspect(); | ||
} | ||
|
||
@Bean | ||
Echo echo() { | ||
return new Echo(); | ||
} | ||
} | ||
|
||
@Configuration | ||
@EnableAspectJAutoProxy(proxyTargetClass = true) | ||
static class AfterAdviceLastConfig { | ||
|
||
@Bean | ||
AfterAdviceLastAspect echoAspect() { | ||
return new AfterAdviceLastAspect(); | ||
} | ||
|
||
@Bean | ||
Echo echo() { | ||
return new Echo(); | ||
} | ||
} | ||
|
||
static class Echo { | ||
|
||
Object echo(Object obj) throws Exception { | ||
if (obj instanceof Exception) { | ||
throw (Exception) obj; | ||
} | ||
return obj; | ||
} | ||
} | ||
|
||
/** | ||
* {@link After @After} advice declared as first <em>after</em> method in source code. | ||
*/ | ||
@Aspect | ||
static class AfterAdviceFirstAspect { | ||
|
||
List<String> invocations = new ArrayList<>(); | ||
|
||
@Pointcut("execution(* echo(*))") | ||
void echo() { | ||
} | ||
|
||
@After("echo()") | ||
void after() { | ||
invocations.add("after"); | ||
} | ||
|
||
@AfterReturning("echo()") | ||
void succeeded() { | ||
invocations.add("after returning"); | ||
} | ||
|
||
@AfterThrowing("echo()") | ||
void failed() { | ||
invocations.add("after throwing"); | ||
} | ||
} | ||
|
||
/** | ||
* {@link After @After} advice declared as last <em>after</em> method in source code. | ||
*/ | ||
@Aspect | ||
static class AfterAdviceLastAspect { | ||
|
||
List<String> invocations = new ArrayList<>(); | ||
|
||
@Pointcut("execution(* echo(*))") | ||
void echo() { | ||
} | ||
|
||
@AfterReturning("echo()") | ||
void succeeded() { | ||
invocations.add("after returning"); | ||
} | ||
|
||
@AfterThrowing("echo()") | ||
void failed() { | ||
invocations.add("after throwing"); | ||
} | ||
|
||
@After("echo()") | ||
void after() { | ||
invocations.add("after"); | ||
} | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
.../springframework/aop/config/AopNamespaceHandlerAdviceOrderIntegrationTests-afterFirst.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?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" | ||
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd | ||
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> | ||
|
||
<bean id="echo" class="org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests$Echo"/> | ||
|
||
<bean id="echoAspect" class="org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests$EchoAspect" /> | ||
|
||
<aop:config> | ||
<aop:aspect id="echoAdvice" ref="echoAspect"> | ||
<aop:pointcut id="echoMethod" expression="execution(* echo(*))" /> | ||
<aop:after method="after" pointcut-ref="echoMethod" /> | ||
<aop:after-throwing method="failed" pointcut-ref="echoMethod" /> | ||
<aop:after-returning method="succeeded" pointcut-ref="echoMethod" /> | ||
</aop:aspect> | ||
</aop:config> | ||
|
||
</beans> |
21 changes: 21 additions & 0 deletions
21
...g/springframework/aop/config/AopNamespaceHandlerAdviceOrderIntegrationTests-afterLast.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?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" | ||
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd | ||
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> | ||
|
||
<bean id="echo" class="org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests$Echo"/> | ||
|
||
<bean id="echoAspect" class="org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests$EchoAspect" /> | ||
|
||
<aop:config> | ||
<aop:aspect id="echoAdvice" ref="echoAspect"> | ||
<aop:pointcut id="echoMethod" expression="execution(* echo(*))" /> | ||
<aop:after-returning method="succeeded" pointcut-ref="echoMethod" /> | ||
<aop:after-throwing method="failed" pointcut-ref="echoMethod" /> | ||
<aop:after method="after" pointcut-ref="echoMethod" /> | ||
</aop:aspect> | ||
</aop:config> | ||
|
||
</beans> |
Oops, something went wrong.