@@ -20,6 +20,9 @@ import kotlinx.coroutines.delay
2020import kotlinx.coroutines.runBlocking
2121import org.aopalliance.intercept.MethodInterceptor
2222import org.aopalliance.intercept.MethodInvocation
23+ import org.aspectj.lang.ProceedingJoinPoint
24+ import org.aspectj.lang.annotation.Around
25+ import org.aspectj.lang.annotation.Aspect
2326import org.assertj.core.api.Assertions.assertThat
2427import org.junit.jupiter.api.Test
2528import org.springframework.aop.framework.autoproxy.AspectJAutoProxyInterceptorKotlinIntegrationTests.InterceptorConfig
@@ -28,10 +31,18 @@ import org.springframework.beans.factory.annotation.Autowired
2831import org.springframework.context.annotation.Bean
2932import org.springframework.context.annotation.Configuration
3033import org.springframework.context.annotation.EnableAspectJAutoProxy
34+ import org.springframework.stereotype.Component
3135import org.springframework.test.annotation.DirtiesContext
3236import org.springframework.test.context.junit.jupiter.SpringJUnitConfig
37+ import org.springframework.transaction.annotation.EnableTransactionManagement
38+ import org.springframework.transaction.annotation.Transactional
39+ import org.springframework.transaction.testfixture.ReactiveCallCountingTransactionManager
3340import reactor.core.publisher.Mono
3441import java.lang.reflect.Method
42+ import kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS
43+ import kotlin.annotation.AnnotationTarget.CLASS
44+ import kotlin.annotation.AnnotationTarget.FUNCTION
45+ import kotlin.annotation.AnnotationTarget.TYPE
3546
3647
3748/* *
@@ -43,7 +54,9 @@ import java.lang.reflect.Method
4354class AspectJAutoProxyInterceptorKotlinIntegrationTests (
4455 @Autowired val echo : Echo ,
4556 @Autowired val firstAdvisor : TestPointcutAdvisor ,
46- @Autowired val secondAdvisor : TestPointcutAdvisor ) {
57+ @Autowired val secondAdvisor : TestPointcutAdvisor ,
58+ @Autowired val countingAspect : CountingAspect ,
59+ @Autowired val reactiveTransactionManager : ReactiveCallCountingTransactionManager ) {
4760
4861 @Test
4962 fun `Multiple interceptors with regular function` () {
@@ -67,8 +80,22 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
6780 assertThat(secondAdvisor.interceptor.invocations).singleElement().matches { Mono ::class .java.isAssignableFrom(it) }
6881 }
6982
83+ @Test // gh-33095
84+ fun `Aspect and reactive transactional with suspending function` () {
85+ assertThat(countingAspect.counter).isZero()
86+ assertThat(reactiveTransactionManager.commits).isZero()
87+ val value = " Hello!"
88+ runBlocking {
89+ assertThat(echo.suspendingTransactionalEcho(value)).isEqualTo(value)
90+ }
91+ assertThat(countingAspect.counter).`as `(" aspect applied" ).isOne()
92+ assertThat(reactiveTransactionManager.begun).isOne()
93+ assertThat(reactiveTransactionManager.commits).`as `(" transactional applied" ).isOne()
94+ }
95+
7096 @Configuration
7197 @EnableAspectJAutoProxy
98+ @EnableTransactionManagement
7299 open class InterceptorConfig {
73100
74101 @Bean
@@ -77,6 +104,13 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
77104 @Bean
78105 open fun secondAdvisor () = TestPointcutAdvisor ().apply { order = 1 }
79106
107+ @Bean
108+ open fun countingAspect () = CountingAspect ()
109+
110+ @Bean
111+ open fun transactionManager (): ReactiveCallCountingTransactionManager {
112+ return ReactiveCallCountingTransactionManager ()
113+ }
80114
81115 @Bean
82116 open fun echo (): Echo {
@@ -107,6 +141,24 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
107141 }
108142 }
109143
144+ @Target(CLASS , FUNCTION , ANNOTATION_CLASS , TYPE )
145+ @Retention(AnnotationRetention .RUNTIME )
146+ annotation class Counting ()
147+
148+ @Aspect
149+ @Component
150+ class CountingAspect {
151+
152+ var counter: Long = 0
153+
154+ @Around(" @annotation(org.springframework.aop.framework.autoproxy.AspectJAutoProxyInterceptorKotlinIntegrationTests.Counting)" )
155+ fun logging (joinPoint : ProceedingJoinPoint ): Any {
156+ return (joinPoint.proceed(joinPoint.args) as Mono <* >).doOnTerminate {
157+ counter++
158+ }
159+ }
160+ }
161+
110162 open class Echo {
111163
112164 open fun echo (value : String ): String {
@@ -118,6 +170,13 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
118170 return value
119171 }
120172
173+ @Transactional
174+ @Counting
175+ open suspend fun suspendingTransactionalEcho (value : String ): String {
176+ delay(1 )
177+ return value
178+ }
179+
121180 }
122181
123182}
0 commit comments