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 37ae3417731..28ece2acf16 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2017 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. @@ -787,11 +787,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac @Override protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) { String factoryBeanName = mbd.getFactoryBeanName(); - final String factoryMethodName = mbd.getFactoryMethodName(); + String factoryMethodName = mbd.getFactoryMethodName(); if (factoryBeanName != null) { if (factoryMethodName != null) { - // Try to obtain the FactoryBean's object type without instantiating it at all. + // Try to obtain the FactoryBean's object type from its factory method declaration + // without instantiating the containing bean at all. BeanDefinition fbDef = getBeanDefinition(factoryBeanName); if (fbDef instanceof AbstractBeanDefinition) { AbstractBeanDefinition afbDef = (AbstractBeanDefinition) fbDef; @@ -811,6 +812,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } + // Let's obtain a shortcut instance for an early getObjectType() call... FactoryBean fb = (mbd.isSingleton() ? getSingletonFactoryBeanForTypeCheck(beanName, mbd) : getNonSingletonFactoryBeanForTypeCheck(beanName, mbd)); @@ -849,12 +851,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac * @param factoryMethodName the name of the factory method * @return the common {@code FactoryBean} object type, or {@code null} if none */ - private Class getTypeForFactoryBeanFromMethod(Class beanClass, String factoryMethodName) { + private Class getTypeForFactoryBeanFromMethod(Class beanClass, final String factoryMethodName) { class Holder { Class value = null; } final Holder objectType = new Holder(); // CGLIB subclass methods hide generic parameters; look at the original user class. Class fbClass = ClassUtils.getUserClass(beanClass); + // Find the given factory method, taking into account that in the case of // @Bean methods, there may be parameters present. ReflectionUtils.doWithMethods(fbClass, @@ -871,6 +874,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } }); + return (objectType.value != null && Object.class != objectType.value ? objectType.value : null); } @@ -921,6 +925,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) { return null; } + Object instance = null; try { // Mark this bean as currently in creation, even if just partially. @@ -936,6 +941,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Finished partial creation of this bean. afterSingletonCreation(beanName); } + FactoryBean fb = getFactoryBean(beanName, instance); if (bw != null) { this.factoryBeanInstanceCache.put(beanName, bw); @@ -956,6 +962,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (isPrototypeCurrentlyInCreation(beanName)) { return null; } + Object instance = null; try { // Mark this bean as currently in creation, even if just partially. @@ -979,6 +986,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Finished partial creation of this bean. afterPrototypeCreation(beanName); } + return getFactoryBean(beanName, instance); }