Remove BeanTypeRegistry
Remove `BeanTypeRegistry` and rely entirely on standard calls Spring Framework APIs. Closes gh-17594
This commit is contained in:
parent
4d21efcc0a
commit
34c31ce099
|
|
@ -1,361 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.condition;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.CannotLoadBeanClassException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.core.type.StandardMethodMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A registry of the bean types that are contained in a
|
||||
* {@link DefaultListableBeanFactory}. Provides similar functionality to
|
||||
* {@link ListableBeanFactory#getBeanNamesForType(Class, boolean, boolean)} but is
|
||||
* optimized for use by {@link OnBeanCondition} based on the following assumptions:
|
||||
* <ul>
|
||||
* <li>Bean definitions will not change type.</li>
|
||||
* <li>Beans definitions will not be removed.</li>
|
||||
* <li>Beans will not be created in parallel.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
final class BeanTypeRegistry implements SmartInitializingSingleton {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BeanTypeRegistry.class);
|
||||
|
||||
static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
|
||||
|
||||
private static final String BEAN_NAME = BeanTypeRegistry.class.getName();
|
||||
|
||||
private final DefaultListableBeanFactory beanFactory;
|
||||
|
||||
private final Map<String, ResolvableType> beanTypes = new HashMap<>();
|
||||
|
||||
private final Map<String, RootBeanDefinition> beanDefinitions = new HashMap<>();
|
||||
|
||||
private BeanTypeRegistry(DefaultListableBeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of beans matching the given type (including subclasses), judging
|
||||
* from either bean definitions or the value of {@link FactoryBean#getObjectType()} in
|
||||
* the case of {@link FactoryBean FactoryBeans}. Will include singletons but will not
|
||||
* cause early bean initialization.
|
||||
* @param type the class or interface to match (must not be {@code null})
|
||||
* @param typeExtractor function used to extract the actual type
|
||||
* @return the names of beans (or objects created by FactoryBeans) matching the given
|
||||
* object type (including subclasses), or an empty set if none
|
||||
*/
|
||||
Set<String> getNamesForType(Class<?> type, TypeExtractor typeExtractor) {
|
||||
updateTypesIfNecessary();
|
||||
return this.beanTypes.entrySet().stream().filter((entry) -> {
|
||||
Class<?> beanType = extractType(entry.getValue(), typeExtractor);
|
||||
return beanType != null && type.isAssignableFrom(beanType);
|
||||
}).map(Map.Entry::getKey).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
private Class<?> extractType(ResolvableType type, TypeExtractor extractor) {
|
||||
return (type != null) ? extractor.getBeanType(type) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of beans annotated with the given {@code annotation}, judging
|
||||
* from either bean definitions or the value of {@link FactoryBean#getObjectType()} in
|
||||
* the case of {@link FactoryBean FactoryBeans}. Will include singletons but will not
|
||||
* cause early bean initialization.
|
||||
* @param annotation the annotation to match (must not be {@code null})
|
||||
* @return the names of beans (or objects created by FactoryBeans) annotated with the
|
||||
* given annotation, or an empty set if none
|
||||
*/
|
||||
Set<String> getNamesForAnnotation(Class<? extends Annotation> annotation) {
|
||||
updateTypesIfNecessary();
|
||||
return this.beanTypes.entrySet().stream()
|
||||
.filter((entry) -> entry.getValue() != null && MergedAnnotations
|
||||
.from(entry.getValue().resolve(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)
|
||||
.isPresent(annotation))
|
||||
.map(Map.Entry::getKey).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
// We're done at this point, free up some memory
|
||||
this.beanTypes.clear();
|
||||
this.beanDefinitions.clear();
|
||||
}
|
||||
|
||||
private void updateTypesIfNecessary() {
|
||||
this.beanFactory.getBeanNamesIterator().forEachRemaining(this::updateTypesIfNecessary);
|
||||
}
|
||||
|
||||
private void updateTypesIfNecessary(String name) {
|
||||
if (!this.beanTypes.containsKey(name)) {
|
||||
addBeanType(name);
|
||||
}
|
||||
else {
|
||||
updateBeanType(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBeanType(String name) {
|
||||
if (this.beanFactory.containsSingleton(name)) {
|
||||
this.beanTypes.put(name, getType(name, null));
|
||||
}
|
||||
else if (!this.beanFactory.isAlias(name)) {
|
||||
addBeanTypeForNonAliasDefinition(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBeanTypeForNonAliasDefinition(String name) {
|
||||
RootBeanDefinition definition = getBeanDefinition(name);
|
||||
if (definition != null) {
|
||||
addBeanTypeForNonAliasDefinition(name, definition);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBeanType(String name) {
|
||||
if (this.beanFactory.isAlias(name) || this.beanFactory.containsSingleton(name)) {
|
||||
return;
|
||||
}
|
||||
RootBeanDefinition definition = getBeanDefinition(name);
|
||||
if (definition == null) {
|
||||
return;
|
||||
}
|
||||
RootBeanDefinition previous = this.beanDefinitions.put(name, definition);
|
||||
if (previous != null && !definition.equals(previous)) {
|
||||
addBeanTypeForNonAliasDefinition(name, definition);
|
||||
}
|
||||
}
|
||||
|
||||
private RootBeanDefinition getBeanDefinition(String name) {
|
||||
try {
|
||||
return (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(name);
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
logIgnoredError("unresolvable metadata in bean definition", name, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void addBeanTypeForNonAliasDefinition(String name, RootBeanDefinition definition) {
|
||||
try {
|
||||
if (!definition.isAbstract() && !requiresEagerInit(definition.getFactoryBeanName())) {
|
||||
ResolvableType factoryMethodReturnType = getFactoryMethodReturnType(definition);
|
||||
String factoryBeanName = BeanFactory.FACTORY_BEAN_PREFIX + name;
|
||||
if (this.beanFactory.isFactoryBean(factoryBeanName)) {
|
||||
ResolvableType factoryBeanGeneric = getFactoryBeanGeneric(this.beanFactory, definition,
|
||||
factoryMethodReturnType);
|
||||
this.beanTypes.put(name, factoryBeanGeneric);
|
||||
this.beanTypes.put(factoryBeanName, getType(factoryBeanName, factoryMethodReturnType));
|
||||
}
|
||||
else {
|
||||
this.beanTypes.put(name, getType(name, factoryMethodReturnType));
|
||||
}
|
||||
}
|
||||
this.beanDefinitions.put(name, definition);
|
||||
}
|
||||
catch (CannotLoadBeanClassException ex) {
|
||||
// Probably contains a placeholder
|
||||
logIgnoredError("bean class loading failure for bean", name, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requiresEagerInit(String factoryBeanName) {
|
||||
return (factoryBeanName != null && this.beanFactory.isFactoryBean(factoryBeanName)
|
||||
&& !this.beanFactory.containsSingleton(factoryBeanName));
|
||||
}
|
||||
|
||||
private ResolvableType getFactoryMethodReturnType(BeanDefinition definition) {
|
||||
try {
|
||||
if (StringUtils.hasLength(definition.getFactoryBeanName())
|
||||
&& StringUtils.hasLength(definition.getFactoryMethodName())) {
|
||||
Method method = getFactoryMethod(this.beanFactory, definition);
|
||||
ResolvableType type = (method != null) ? ResolvableType.forMethodReturnType(method) : null;
|
||||
return type;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Method getFactoryMethod(ConfigurableListableBeanFactory beanFactory, BeanDefinition definition)
|
||||
throws Exception {
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) definition).getFactoryMethodMetadata();
|
||||
if (factoryMethodMetadata instanceof StandardMethodMetadata) {
|
||||
return ((StandardMethodMetadata) factoryMethodMetadata).getIntrospectedMethod();
|
||||
}
|
||||
}
|
||||
BeanDefinition factoryDefinition = beanFactory.getBeanDefinition(definition.getFactoryBeanName());
|
||||
Class<?> factoryClass = ClassUtils.forName(factoryDefinition.getBeanClassName(),
|
||||
beanFactory.getBeanClassLoader());
|
||||
return getFactoryMethod(definition, factoryClass);
|
||||
}
|
||||
|
||||
private Method getFactoryMethod(BeanDefinition definition, Class<?> factoryClass) {
|
||||
Method uniqueMethod = null;
|
||||
for (Method candidate : getCandidateFactoryMethods(definition, factoryClass)) {
|
||||
if (candidate.getName().equals(definition.getFactoryMethodName())) {
|
||||
if (uniqueMethod == null) {
|
||||
uniqueMethod = candidate;
|
||||
}
|
||||
else if (!hasMatchingParameterTypes(candidate, uniqueMethod)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return uniqueMethod;
|
||||
}
|
||||
|
||||
private Method[] getCandidateFactoryMethods(BeanDefinition definition, Class<?> factoryClass) {
|
||||
return (shouldConsiderNonPublicMethods(definition) ? ReflectionUtils.getAllDeclaredMethods(factoryClass)
|
||||
: factoryClass.getMethods());
|
||||
}
|
||||
|
||||
private boolean shouldConsiderNonPublicMethods(BeanDefinition definition) {
|
||||
return (definition instanceof AbstractBeanDefinition)
|
||||
&& ((AbstractBeanDefinition) definition).isNonPublicAccessAllowed();
|
||||
}
|
||||
|
||||
private boolean hasMatchingParameterTypes(Method candidate, Method current) {
|
||||
return Arrays.equals(candidate.getParameterTypes(), current.getParameterTypes());
|
||||
}
|
||||
|
||||
private void logIgnoredError(String message, String name, Exception ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring " + message + " '" + name + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to guess the type that a {@link FactoryBean} will return based on the
|
||||
* generics in its method signature.
|
||||
* @param beanFactory the source bean factory
|
||||
* @param definition the bean definition
|
||||
* @param factoryMethodReturnType the factory method return type
|
||||
* @return the generic type of the {@link FactoryBean} or {@code null}
|
||||
*/
|
||||
private ResolvableType getFactoryBeanGeneric(ConfigurableListableBeanFactory beanFactory, BeanDefinition definition,
|
||||
ResolvableType factoryMethodReturnType) {
|
||||
try {
|
||||
if (factoryMethodReturnType != null) {
|
||||
return getFactoryBeanType(definition, factoryMethodReturnType);
|
||||
}
|
||||
if (StringUtils.hasLength(definition.getBeanClassName())) {
|
||||
return getDirectFactoryBeanGeneric(beanFactory, definition);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ResolvableType getDirectFactoryBeanGeneric(ConfigurableListableBeanFactory beanFactory,
|
||||
BeanDefinition definition) throws ClassNotFoundException, LinkageError {
|
||||
Class<?> factoryBeanClass = ClassUtils.forName(definition.getBeanClassName(), beanFactory.getBeanClassLoader());
|
||||
return getFactoryBeanType(definition, ResolvableType.forClass(factoryBeanClass));
|
||||
}
|
||||
|
||||
private ResolvableType getFactoryBeanType(BeanDefinition definition, ResolvableType type)
|
||||
throws ClassNotFoundException, LinkageError {
|
||||
ResolvableType generic = type.as(FactoryBean.class).getGeneric();
|
||||
if ((generic == null || generic.resolve().equals(Object.class))
|
||||
&& definition.hasAttribute(FACTORY_BEAN_OBJECT_TYPE)) {
|
||||
generic = getTypeFromAttribute(definition.getAttribute(FACTORY_BEAN_OBJECT_TYPE));
|
||||
}
|
||||
return generic;
|
||||
}
|
||||
|
||||
private ResolvableType getTypeFromAttribute(Object attribute) throws ClassNotFoundException, LinkageError {
|
||||
if (attribute instanceof Class<?>) {
|
||||
return ResolvableType.forClass((Class<?>) attribute);
|
||||
}
|
||||
if (attribute instanceof String) {
|
||||
return ResolvableType.forClass(ClassUtils.forName((String) attribute, null));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ResolvableType getType(String name, ResolvableType factoryMethodReturnType) {
|
||||
if (factoryMethodReturnType != null && !factoryMethodReturnType.resolve(Object.class).equals(Object.class)) {
|
||||
return factoryMethodReturnType;
|
||||
}
|
||||
Class<?> type = this.beanFactory.getType(name);
|
||||
return (type != null) ? ResolvableType.forClass(type) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to get the {@link BeanTypeRegistry} for a given {@link BeanFactory}.
|
||||
* @param beanFactory the source bean factory
|
||||
* @return the {@link BeanTypeRegistry} for the given bean factory
|
||||
*/
|
||||
static BeanTypeRegistry get(ListableBeanFactory beanFactory) {
|
||||
Assert.isInstanceOf(DefaultListableBeanFactory.class, beanFactory);
|
||||
DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) beanFactory;
|
||||
Assert.isTrue(listableBeanFactory.isAllowEagerClassLoading(), "Bean factory must allow eager class loading");
|
||||
if (!listableBeanFactory.containsLocalBean(BEAN_NAME)) {
|
||||
BeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(BeanTypeRegistry.class,
|
||||
() -> new BeanTypeRegistry((DefaultListableBeanFactory) beanFactory)).getBeanDefinition();
|
||||
listableBeanFactory.registerBeanDefinition(BEAN_NAME, definition);
|
||||
}
|
||||
return listableBeanFactory.getBean(BEAN_NAME, BeanTypeRegistry.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used to extract the actual bean type from a source {@link ResolvableType}.
|
||||
* May be used to support parameterized containers for beans.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface TypeExtractor {
|
||||
|
||||
Class<?> getBeanType(ResolvableType type);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,7 +36,6 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
|
||||
import org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.TypeExtractor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
|
|
@ -56,6 +55,7 @@ import org.springframework.util.Assert;
|
|||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
|
@ -74,8 +74,6 @@ import org.springframework.util.StringUtils;
|
|||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
class OnBeanCondition extends FilteringSpringBootCondition implements ConfigurationCondition {
|
||||
|
||||
private static final TypeExtractor RESOLVING_EXTRACTOR = ResolvableType::resolve;
|
||||
|
||||
@Override
|
||||
public ConfigurationPhase getConfigurationPhase() {
|
||||
return ConfigurationPhase.REGISTER_BEAN;
|
||||
|
|
@ -228,8 +226,11 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
|
|||
|
||||
private Set<String> collectBeanNamesForType(ListableBeanFactory beanFactory, boolean considerHierarchy,
|
||||
Class<?> type, Set<Class<?>> parameterizedContainers, Set<String> result) {
|
||||
BeanTypeRegistry registry = BeanTypeRegistry.get(beanFactory);
|
||||
result = addAll(result, registry.getNamesForType(type, getTypeExtractor(parameterizedContainers)));
|
||||
result = addAll(result, beanFactory.getBeanNamesForType(type, true, false));
|
||||
for (Class<?> container : parameterizedContainers) {
|
||||
ResolvableType generic = ResolvableType.forClassWithGenerics(container, type);
|
||||
result = addAll(result, beanFactory.getBeanNamesForType(generic, true, false));
|
||||
}
|
||||
if (considerHierarchy && beanFactory instanceof HierarchicalBeanFactory) {
|
||||
BeanFactory parent = ((HierarchicalBeanFactory) beanFactory).getParentBeanFactory();
|
||||
if (parent instanceof ListableBeanFactory) {
|
||||
|
|
@ -261,8 +262,7 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
|
|||
|
||||
private Set<String> collectBeanNamesForAnnotation(ListableBeanFactory beanFactory,
|
||||
Class<? extends Annotation> annotationType, boolean considerHierarchy, Set<String> result) {
|
||||
BeanTypeRegistry registry = BeanTypeRegistry.get(beanFactory);
|
||||
result = addAll(result, registry.getNamesForAnnotation(annotationType));
|
||||
result = addAll(result, beanFactory.getBeanNamesForAnnotation(annotationType));
|
||||
if (considerHierarchy) {
|
||||
BeanFactory parent = ((HierarchicalBeanFactory) beanFactory).getParentBeanFactory();
|
||||
if (parent instanceof ListableBeanFactory) {
|
||||
|
|
@ -281,15 +281,6 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
|
|||
return beanFactory.containsLocalBean(beanName);
|
||||
}
|
||||
|
||||
private Set<String> addAll(Set<String> result, Collection<String> additional) {
|
||||
if (CollectionUtils.isEmpty(additional)) {
|
||||
return result;
|
||||
}
|
||||
result = (result != null) ? result : new LinkedHashSet<>();
|
||||
result.addAll(additional);
|
||||
return result;
|
||||
}
|
||||
|
||||
private String createOnBeanNoMatchReason(MatchResult matchResult) {
|
||||
StringBuilder reason = new StringBuilder();
|
||||
appendMessageForNoMatches(reason, matchResult.getUnmatchedAnnotations(), "annotated with");
|
||||
|
|
@ -370,26 +361,24 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
|
|||
return null;
|
||||
}
|
||||
|
||||
private TypeExtractor getTypeExtractor(Set<Class<?>> parameterizedContainers) {
|
||||
if (parameterizedContainers.isEmpty()) {
|
||||
return RESOLVING_EXTRACTOR;
|
||||
private static Set<String> addAll(Set<String> result, Collection<String> additional) {
|
||||
if (CollectionUtils.isEmpty(additional)) {
|
||||
return result;
|
||||
}
|
||||
return (type) -> {
|
||||
Class<?> resolved = RESOLVING_EXTRACTOR.getBeanType(type);
|
||||
if (isParameterizedContainer(resolved, parameterizedContainers)) {
|
||||
resolved = type.getGeneric().resolve();
|
||||
}
|
||||
return resolved;
|
||||
};
|
||||
result = (result != null) ? result : new LinkedHashSet<>();
|
||||
result.addAll(additional);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isParameterizedContainer(Class<?> type, Set<Class<?>> parameterizedContainers) {
|
||||
for (Class<?> parameterizedContainer : parameterizedContainers) {
|
||||
if (parameterizedContainer.isAssignableFrom(type)) {
|
||||
return true;
|
||||
}
|
||||
private static Set<String> addAll(Set<String> result, String[] additional) {
|
||||
if (ObjectUtils.isEmpty(additional)) {
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
result = (result != null) ? result : new LinkedHashSet<>();
|
||||
for (String addition : additional) {
|
||||
result.add(addition);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ public class ConditionalOnMissingBeanTests {
|
|||
public void registerBeanDefinitions(AnnotationMetadata meta, BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(NonspecificFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
builder.getBeanDefinition().setAttribute(BeanTypeRegistry.FACTORY_BEAN_OBJECT_TYPE, ExampleBean.class);
|
||||
builder.getBeanDefinition().setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, ExampleBean.class);
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean", builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
|
|
@ -456,8 +456,7 @@ public class ConditionalOnMissingBeanTests {
|
|||
public void registerBeanDefinitions(AnnotationMetadata meta, BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(NonspecificFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
builder.getBeanDefinition().setAttribute(BeanTypeRegistry.FACTORY_BEAN_OBJECT_TYPE,
|
||||
ExampleBean.class.getName());
|
||||
builder.getBeanDefinition().setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, ExampleBean.class.getName());
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean", builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ import org.springframework.util.StringUtils;
|
|||
public class MockitoPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
|
||||
implements BeanClassLoaderAware, BeanFactoryAware, BeanFactoryPostProcessor, Ordered {
|
||||
|
||||
private static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
|
||||
|
||||
private static final String BEAN_NAME = MockitoPostProcessor.class.getName();
|
||||
|
||||
private static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions
|
||||
|
|
@ -254,7 +252,7 @@ public class MockitoPostProcessor extends InstantiationAwareBeanPostProcessorAda
|
|||
for (String beanName : beanFactory.getBeanNamesForType(FactoryBean.class)) {
|
||||
beanName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||
if (typeName.equals(beanDefinition.getAttribute(FACTORY_BEAN_OBJECT_TYPE))) {
|
||||
if (typeName.equals(beanDefinition.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE))) {
|
||||
beans.add(beanName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class MockitoPostProcessorTests {
|
|||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
MockitoPostProcessor.register(context);
|
||||
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition(TestFactoryBean.class);
|
||||
factoryBeanDefinition.setAttribute("factoryBeanObjectType", SomeInterface.class.getName());
|
||||
factoryBeanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, SomeInterface.class.getName());
|
||||
context.registerBeanDefinition("beanToBeMocked", factoryBeanDefinition);
|
||||
context.register(MockedFactoryBean.class);
|
||||
context.refresh();
|
||||
|
|
|
|||
Loading…
Reference in New Issue