From 28f7b262940debda61acf0b7bb18103b9228a0cf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 18 Jul 2018 15:26:06 +0200 Subject: [PATCH] Null-returning instance supplier resolves to NullBean Issue: SPR-17057 --- .../AbstractAutowireCapableBeanFactory.java | 7 ++++++- ...notationConfigApplicationContextTests.java | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index c21f498d812..c7988000108 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1148,9 +1148,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac * @see #getObjectForBeanInstance */ protected BeanWrapper obtainFromSupplier(Supplier instanceSupplier, String beanName) { + Object instance; + String outerBean = this.currentlyCreatedBean.get(); this.currentlyCreatedBean.set(beanName); - Object instance; try { instance = instanceSupplier.get(); } @@ -1162,6 +1163,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac this.currentlyCreatedBean.remove(); } } + + if (instance == null) { + instance = new NullBean(); + } BeanWrapper bw = new BeanWrapperImpl(instance); initBeanWrapper(bw); return bw; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java b/spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java index 5baa61ba3e1..7f9a1aafca7 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -29,8 +29,9 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation6.ComponentForScanning; import org.springframework.context.annotation6.ConfigForScanning; import org.springframework.context.annotation6.Jsr330NamedForScanning; +import org.springframework.util.ObjectUtils; -import static java.lang.String.format; +import static java.lang.String.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.springframework.util.StringUtils.*; @@ -210,6 +211,22 @@ public class AnnotationConfigApplicationContextTests { assertSame(context, context.getBean("b", BeanB.class).applicationContext); } + @Test + public void individualBeanWithNullReturningSupplier() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.registerBean("a", BeanA.class, () -> null); + context.registerBean("b", BeanB.class, BeanB::new); + context.registerBean("c", BeanC.class, BeanC::new); + context.refresh(); + + assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanA.class), "a")); + assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanB.class), "b")); + assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanC.class), "c")); + assertTrue(context.getBeansOfType(BeanA.class).isEmpty()); + assertSame(context.getBean(BeanB.class), context.getBeansOfType(BeanB.class).values().iterator().next()); + assertSame(context.getBean(BeanC.class), context.getBeansOfType(BeanC.class).values().iterator().next()); + } + @Test public void individualBeanWithSpecifiedConstructorArguments() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();