Skip to content

Commit 3bd96f7

Browse files
committed
Leniently tolerate null bean as aspect instance
Closes gh-35074
1 parent ad00aeb commit 3bd96f7

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -618,28 +618,35 @@ else if (this.joinPointStaticPartArgumentIndex != -1) {
618618
* @return the invocation result
619619
* @throws Throwable in case of invocation failure
620620
*/
621-
protected Object invokeAdviceMethod(
622-
@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)
623-
throws Throwable {
621+
protected @Nullable Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch,
622+
@Nullable Object returnValue, @Nullable Throwable ex) throws Throwable {
624623

625624
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
626625
}
627626

628627
// As above, but in this case we are given the join point.
629-
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
628+
protected @Nullable Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
630629
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
631630

632631
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
633632
}
634633

635-
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
634+
protected @Nullable Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
636635
Object[] actualArgs = args;
637636
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
638637
actualArgs = null;
639638
}
639+
Object aspectInstance = this.aspectInstanceFactory.getAspectInstance();
640+
if (aspectInstance.equals(null)) {
641+
// Possibly a NullBean -> simply proceed if necessary.
642+
if (getJoinPoint() instanceof ProceedingJoinPoint pjp) {
643+
return pjp.proceed();
644+
}
645+
return null;
646+
}
640647
try {
641648
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
642-
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
649+
return this.aspectJAdviceMethod.invoke(aspectInstance, actualArgs);
643650
}
644651
catch (IllegalArgumentException ex) {
645652
throw new AopInvocationException("Mismatch on arguments to advice method [" +

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.Serializable;
2020

2121
import org.springframework.beans.factory.BeanFactory;
22+
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
2223
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
2324
import org.springframework.core.Ordered;
2425
import org.springframework.core.annotation.OrderUtils;
@@ -130,7 +131,12 @@ public int getOrder() {
130131
Class<?> type = this.beanFactory.getType(this.name);
131132
if (type != null) {
132133
if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
133-
return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
134+
try {
135+
return this.beanFactory.getBean(this.name, Ordered.class).getOrder();
136+
}
137+
catch (BeanNotOfRequiredTypeException ex) {
138+
// Not actually implementing Ordered -> possibly a NullBean.
139+
}
134140
}
135141
return OrderUtils.getOrder(type, Ordered.LOWEST_PRECEDENCE);
136142
}

spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,16 @@ void lambdaIsAlwaysProxiedWithJdkProxyWithIntroductions(Class<?> configClass) {
364364
}
365365
}
366366

367+
@Test
368+
void nullAdviceIsSkipped() {
369+
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ProxyWithNullAdviceConfig.class)) {
370+
@SuppressWarnings("unchecked")
371+
Supplier<String> supplier = context.getBean(Supplier.class);
372+
assertThat(AopUtils.isAopProxy(supplier)).as("AOP proxy").isTrue();
373+
assertThat(supplier.get()).isEqualTo("lambda");
374+
}
375+
}
376+
367377
private ClassPathXmlApplicationContext newContext(String fileSuffix) {
368378
return new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-" + fileSuffix, getClass());
369379
}
@@ -627,6 +637,16 @@ class ProxyTargetClassFalseConfig extends AbstractProxyTargetClassConfig {
627637
class ProxyTargetClassTrueConfig extends AbstractProxyTargetClassConfig {
628638
}
629639

640+
@Configuration(proxyBeanMethods = false)
641+
@EnableAspectJAutoProxy(proxyTargetClass = true)
642+
class ProxyWithNullAdviceConfig extends AbstractProxyTargetClassConfig {
643+
644+
@Override
645+
SupplierAdvice supplierAdvice() {
646+
return null;
647+
}
648+
}
649+
630650
@Configuration
631651
@EnableAspectJAutoProxy(proxyTargetClass = true)
632652
class PerTargetProxyTargetClassTrueConfig {

0 commit comments

Comments
 (0)