From 21cb9e8bffd11442469195dc7e0d5cbe5b6e148f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 25 Sep 2020 11:24:50 +0200 Subject: [PATCH] Translate NullBean result to null for lookup method with bean name Closes gh-25806 --- .../CglibSubclassingInstantiationStrategy.java | 6 ++++-- .../annotation/LookupAnnotationTests.java | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java index 88e9942e80..698a04d249 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * 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. @@ -238,8 +238,10 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt Assert.state(lo != null, "LookupOverride not found"); Object[] argsToUse = (args.length > 0 ? args : null); // if no-arg, don't insist on args at all if (StringUtils.hasText(lo.getBeanName())) { - return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) : + Object bean = (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) : this.owner.getBean(lo.getBeanName())); + // Detect package-protected NullBean instance through equals(null) check + return (bean.equals(null) ? null : bean); } else { return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) : diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/LookupAnnotationTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/LookupAnnotationTests.java index d9b198e3e3..bd30b5b44c 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/LookupAnnotationTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/LookupAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * 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. @@ -108,10 +108,23 @@ public class LookupAnnotationTests { assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean); } + @Test // gh-25806 + public void testWithNullBean() { + RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class, () -> null); + tbd.setScope(BeanDefinition.SCOPE_PROTOTYPE); + beanFactory.registerBeanDefinition("testBean", tbd); + + AbstractBean bean = beanFactory.getBean("beanConsumer", BeanConsumer.class).abstractBean; + assertThat(bean).isNotNull(); + Object expected = bean.get(); + assertThat(expected).isNull(); + assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean); + } + public static abstract class AbstractBean { - @Lookup + @Lookup("testBean") public abstract TestBean get(); @Lookup