Skip to content

Commit 43107e7

Browse files
committed
Propagate arguments for dynamic prototype-scoped advice
Closes gh-28407
1 parent 81bd6be commit 43107e7

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -293,7 +293,7 @@ public boolean matches(Method method, Class<?> targetClass) {
293293
@Override
294294
public boolean matches(Method method, Class<?> targetClass, Object... args) {
295295
// This can match only on declared pointcut.
296-
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
296+
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass, args));
297297
}
298298

299299
private boolean isAspectMaterialized() {

spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/ArgumentBindingTests.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,26 +42,38 @@
4242
*/
4343
class ArgumentBindingTests {
4444

45+
@Test
46+
void annotationArgumentNameBinding() {
47+
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TransactionalBean());
48+
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
49+
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
50+
51+
assertThatIllegalStateException()
52+
.isThrownBy(proxiedTestBean::doInTransaction)
53+
.withMessage("Invoked with @Transactional");
54+
}
55+
4556
@Test
4657
void bindingInPointcutUsedByAdvice() {
4758
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
4859
proxyFactory.addAspect(NamedPointcutWithArgs.class);
49-
5060
ITestBean proxiedTestBean = proxyFactory.getProxy();
61+
5162
assertThatIllegalArgumentException()
52-
.isThrownBy(() -> proxiedTestBean.setName("enigma"))
53-
.withMessage("enigma");
63+
.isThrownBy(() -> proxiedTestBean.setName("enigma"))
64+
.withMessage("enigma");
5465
}
5566

5667
@Test
57-
void annotationArgumentNameBinding() {
58-
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TransactionalBean());
59-
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
68+
void bindingWithDynamicAdvice() {
69+
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
70+
proxyFactory.addAspect(DynamicPointcutWithArgs.class);
71+
ITestBean proxiedTestBean = proxyFactory.getProxy();
6072

61-
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
62-
assertThatIllegalStateException()
63-
.isThrownBy(proxiedTestBean::doInTransaction)
64-
.withMessage("Invoked with @Transactional");
73+
proxiedTestBean.applyName(1);
74+
assertThatIllegalArgumentException()
75+
.isThrownBy(() -> proxiedTestBean.applyName("enigma"))
76+
.withMessage("enigma");
6577
}
6678

6779
@Test
@@ -94,23 +106,25 @@ public void doInTransaction() {
94106
}
95107
}
96108

109+
97110
/**
98111
* Mimics Spring's @Transactional annotation without actually introducing the dependency.
99112
*/
100113
@Retention(RetentionPolicy.RUNTIME)
101114
@interface Transactional {
102115
}
103116

117+
104118
@Aspect
105119
static class PointcutWithAnnotationArgument {
106120

107-
@Around(value = "execution(* org.springframework..*.*(..)) && @annotation(transactional)")
121+
@Around("execution(* org.springframework..*.*(..)) && @annotation(transactional)")
108122
public Object around(ProceedingJoinPoint pjp, Transactional transactional) throws Throwable {
109123
throw new IllegalStateException("Invoked with @Transactional");
110124
}
111-
112125
}
113126

127+
114128
@Aspect
115129
static class NamedPointcutWithArgs {
116130

@@ -121,7 +135,16 @@ public void pointcutWithArgs(String s) {}
121135
public Object doAround(ProceedingJoinPoint pjp, String aString) throws Throwable {
122136
throw new IllegalArgumentException(aString);
123137
}
138+
}
124139

140+
141+
@Aspect("pertarget(execution(* *(..)))")
142+
static class DynamicPointcutWithArgs {
143+
144+
@Around("execution(* *(..)) && args(java.lang.String)")
145+
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
146+
throw new IllegalArgumentException(String.valueOf(pjp.getArgs()[0]));
147+
}
125148
}
126149

127150
}

spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/ITestBean.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,10 @@ public interface ITestBean extends AgeHolder {
3333

3434
void setName(String name);
3535

36+
default void applyName(Object name) {
37+
setName(String.valueOf(name));
38+
}
39+
3640
ITestBean getSpouse();
3741

3842
void setSpouse(ITestBean spouse);

0 commit comments

Comments
 (0)