|
|
|
|
@ -23,7 +23,6 @@ import java.util.Set;
@@ -23,7 +23,6 @@ import java.util.Set;
|
|
|
|
|
|
|
|
|
|
import org.springframework.aop.scope.ScopedProxyUtils; |
|
|
|
|
import org.springframework.beans.BeansException; |
|
|
|
|
import org.springframework.beans.factory.BeanFactory; |
|
|
|
|
import org.springframework.beans.factory.BeanFactoryUtils; |
|
|
|
|
import org.springframework.beans.factory.FactoryBean; |
|
|
|
|
import org.springframework.beans.factory.NoUniqueBeanDefinitionException; |
|
|
|
|
@ -44,7 +43,7 @@ import org.springframework.util.Assert;
@@ -44,7 +43,7 @@ import org.springframework.util.Assert;
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A {@link BeanFactoryPostProcessor} implementation that processes identified |
|
|
|
|
* use of {@link BeanOverride @BeanOverride} and adapts the {@link BeanFactory} |
|
|
|
|
* use of {@link BeanOverride @BeanOverride} and adapts the {@code BeanFactory} |
|
|
|
|
* accordingly. |
|
|
|
|
* |
|
|
|
|
* <p>For each override, the bean factory is prepared according to the chosen |
|
|
|
|
@ -119,9 +118,16 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -119,9 +118,16 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
|
|
|
|
|
// NOTE: This method supports 3 distinct scenarios which must be accounted for.
|
|
|
|
|
//
|
|
|
|
|
// 1) JVM runtime
|
|
|
|
|
// 2) AOT processing
|
|
|
|
|
// 3) AOT runtime
|
|
|
|
|
// - JVM runtime
|
|
|
|
|
// - AOT processing
|
|
|
|
|
// - AOT runtime
|
|
|
|
|
//
|
|
|
|
|
// In addition, this method supports 4 distinct use cases.
|
|
|
|
|
//
|
|
|
|
|
// 1) Override existing bean by-type
|
|
|
|
|
// 2) Create bean by-type, with a generated name
|
|
|
|
|
// 3) Override existing bean by-name
|
|
|
|
|
// 4) Create bean by-name, with a provided name
|
|
|
|
|
|
|
|
|
|
String beanName = handler.getBeanName(); |
|
|
|
|
Field field = handler.getField(); |
|
|
|
|
@ -129,7 +135,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -129,7 +135,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
if (beanName == null) { |
|
|
|
|
beanName = getBeanNameForType(beanFactory, handler, requireExistingBean); |
|
|
|
|
if (beanName != null) { |
|
|
|
|
// We are overriding an existing bean by-type.
|
|
|
|
|
// 1) We are overriding an existing bean by-type.
|
|
|
|
|
beanName = BeanFactoryUtils.transformedBeanName(beanName); |
|
|
|
|
// If we are overriding a manually registered singleton, we won't find
|
|
|
|
|
// an existing bean definition.
|
|
|
|
|
@ -138,15 +144,16 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -138,15 +144,16 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
// We will later generate a name for the nonexistent bean, but since NullAway
|
|
|
|
|
// will reject leaving the beanName set to null, we set it to a placeholder.
|
|
|
|
|
// 2) We are creating a bean by-type, with a generated name.
|
|
|
|
|
// Since NullAway will reject leaving the beanName set to null,
|
|
|
|
|
// we set it to a placeholder that will be replaced later.
|
|
|
|
|
beanName = PSEUDO_BEAN_NAME_PLACEHOLDER; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
Set<String> candidates = getExistingBeanNamesByType(beanFactory, handler, false); |
|
|
|
|
if (candidates.contains(beanName)) { |
|
|
|
|
// We are overriding an existing bean by-name.
|
|
|
|
|
// 3) We are overriding an existing bean by-name.
|
|
|
|
|
existingBeanDefinition = beanFactory.getBeanDefinition(beanName); |
|
|
|
|
} |
|
|
|
|
else if (requireExistingBean) { |
|
|
|
|
@ -156,6 +163,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -156,6 +163,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
.formatted(beanName, handler.getBeanType(), |
|
|
|
|
field.getDeclaringClass().getSimpleName(), field.getName())); |
|
|
|
|
} |
|
|
|
|
// 4) We are creating a bean by-name with the provided beanName.
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (existingBeanDefinition != null) { |
|
|
|
|
@ -214,11 +222,14 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -214,11 +222,14 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check that a bean with the specified {@link BeanOverrideHandler#getBeanName() name} |
|
|
|
|
* and {@link BeanOverrideHandler#getBeanType() type} is registered. |
|
|
|
|
* <p>If so, put the {@link BeanOverrideHandler} in the early tracking map. |
|
|
|
|
* <p>The map will later be checked to see if a given bean should be wrapped |
|
|
|
|
* upon creation, during the {@link WrapEarlyBeanPostProcessor#getEarlyBeanReference} |
|
|
|
|
* phase. |
|
|
|
|
* or {@link BeanOverrideHandler#getBeanType() type} has already been registered |
|
|
|
|
* in the {@code BeanFactory}. |
|
|
|
|
* <p>If so, register the {@link BeanOverrideHandler} and the corresponding bean |
|
|
|
|
* name in the {@link BeanOverrideRegistry}. |
|
|
|
|
* <p>The registry will later be checked to see if a given bean should be wrapped |
|
|
|
|
* upon creation, during the early bean post-processing phase. |
|
|
|
|
* @see BeanOverrideRegistry#registerBeanOverrideHandler(BeanOverrideHandler, String) |
|
|
|
|
* @see WrapEarlyBeanPostProcessor#getEarlyBeanReference(Object, String) |
|
|
|
|
*/ |
|
|
|
|
private void wrapBean(ConfigurableListableBeanFactory beanFactory, BeanOverrideHandler handler) { |
|
|
|
|
String beanName = handler.getBeanName(); |
|
|
|
|
@ -393,7 +404,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@@ -393,7 +404,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
|
|
|
|
* respectively. |
|
|
|
|
* <p>The returned bean definition should <strong>not</strong> be used to create |
|
|
|
|
* a bean instance but rather only for the purpose of having suitable bean |
|
|
|
|
* definition metadata available in the {@link BeanFactory} — for example, |
|
|
|
|
* definition metadata available in the {@code BeanFactory} — for example, |
|
|
|
|
* for autowiring candidate resolution. |
|
|
|
|
*/ |
|
|
|
|
private static RootBeanDefinition createPseudoBeanDefinition(BeanOverrideHandler handler) { |
|
|
|
|
|