diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 5e60733ca7..7f93df817b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.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. @@ -552,7 +552,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp // Check bean class whether we're dealing with a FactoryBean. if (FactoryBean.class.isAssignableFrom(beanType)) { - if (!BeanFactoryUtils.isFactoryDereference(name)) { + if (!BeanFactoryUtils.isFactoryDereference(name) && beanInstance == null) { // If it's a FactoryBean, we want to look at what it creates, not the factory class. beanType = getTypeForFactoryBean(beanName, mbd); if (beanType == null) { @@ -1614,8 +1614,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. - if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { - throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); + if (BeanFactoryUtils.isFactoryDereference(name)) { + if (beanInstance instanceof NullBean) { + return beanInstance; + } + if (!(beanInstance instanceof FactoryBean)) { + throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); + } } // Now we have the bean instance, which may be a normal bean or a FactoryBean. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index fe819043a7..7a28ef5566 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.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. @@ -739,19 +739,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { - final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); - boolean isEagerInit; - if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { - isEagerInit = AccessController.doPrivileged((PrivilegedAction) () -> - ((SmartFactoryBean) factory).isEagerInit(), - getAccessControlContext()); - } - else { - isEagerInit = (factory instanceof SmartFactoryBean && - ((SmartFactoryBean) factory).isEagerInit()); - } - if (isEagerInit) { - getBean(beanName); + Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); + if (bean instanceof FactoryBean) { + final FactoryBean factory = (FactoryBean) bean; + boolean isEagerInit; + if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { + isEagerInit = AccessController.doPrivileged((PrivilegedAction) () -> + ((SmartFactoryBean) factory).isEagerInit(), + getAccessControlContext()); + } + else { + isEagerInit = (factory instanceof SmartFactoryBean && + ((SmartFactoryBean) factory).isEagerInit()); + } + if (isEagerInit) { + getBean(beanName); + } } } else { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 498da1c429..56373e04eb 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.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. @@ -1132,6 +1132,11 @@ public class ConfigurationClassPostProcessorTests { public RepositoryFactoryBean repoFactoryBean() { return new RepositoryFactoryBean<>(); } + + @Bean + public FactoryBean nullFactoryBean() { + return null; + } } @Configuration