Skip to content

Commit dfa948c

Browse files
committed
Introduce AutowireCandidateResolver.cloneIfNecessary() method
Closes gh-25131
1 parent f9aae8d commit dfa948c

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.beans.factory.support;
1818

19+
import org.springframework.beans.BeanUtils;
1920
import org.springframework.beans.factory.config.BeanDefinitionHolder;
2021
import org.springframework.beans.factory.config.DependencyDescriptor;
2122
import org.springframework.lang.Nullable;
@@ -99,4 +100,22 @@ default Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor
99100
return null;
100101
}
101102

103+
/**
104+
* Return a clone of this resolver instance if necessary, retaining its local
105+
* configuration and allowing for the cloned instance to get associated with
106+
* a new bean factory, or this original instance if there is no such state.
107+
* <p>The default implementation creates a separate instance via the default
108+
* class constructor, assuming no specific configuration state to copy.
109+
* Subclasses may override this with custom configuration state handling
110+
* or with standard {@link Cloneable} support (as implemented by Spring's
111+
* own configurable {@code AutowireCandidateResolver} variants), or simply
112+
* return {@code this} (as in {@link SimpleAutowireCandidateResolver}).
113+
* @since 5.2.7
114+
* @see GenericTypeAwareAutowireCandidateResolver#cloneIfNecessary()
115+
* @see DefaultListableBeanFactory#copyConfigurationFrom
116+
*/
117+
default AutowireCandidateResolver cloneIfNecessary() {
118+
return BeanUtils.instantiateClass(getClass());
119+
}
120+
102121
}

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646

4747
import javax.inject.Provider;
4848

49-
import org.springframework.beans.BeanUtils;
5049
import org.springframework.beans.BeansException;
5150
import org.springframework.beans.TypeConverter;
5251
import org.springframework.beans.factory.BeanCreationException;
@@ -157,7 +156,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
157156
private Comparator<Object> dependencyComparator;
158157

159158
/** Resolver to use for checking if a bean definition is an autowire candidate. */
160-
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
159+
private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
161160

162161
/** Map from dependency type to corresponding autowired value. */
163162
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
@@ -328,8 +327,7 @@ public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
328327
this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
329328
this.dependencyComparator = otherListableFactory.dependencyComparator;
330329
// A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware...
331-
setAutowireCandidateResolver(
332-
BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass()));
330+
setAutowireCandidateResolver(otherListableFactory.getAutowireCandidateResolver().cloneIfNecessary());
333331
// Make resolvable dependencies (e.g. ResourceLoader) available here as well...
334332
this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
335333
}

spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@
4343
* @since 4.0
4444
*/
4545
public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCandidateResolver
46-
implements BeanFactoryAware {
46+
implements BeanFactoryAware, Cloneable {
4747

4848
@Nullable
4949
private BeanFactory beanFactory;
@@ -177,4 +177,21 @@ protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, D
177177
return null;
178178
}
179179

180+
181+
/**
182+
* This implementation clones all instance fields through standard
183+
* {@link Cloneable} support, allowing for subsequent reconfiguration
184+
* of the cloned instance through a fresh {@link #setBeanFactory} call.
185+
* @see #clone()
186+
*/
187+
@Override
188+
public AutowireCandidateResolver cloneIfNecessary() {
189+
try {
190+
return (AutowireCandidateResolver) clone();
191+
}
192+
catch (CloneNotSupportedException ex) {
193+
throw new IllegalStateException(ex);
194+
}
195+
}
196+
180197
}

spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,13 @@
3030
*/
3131
public class SimpleAutowireCandidateResolver implements AutowireCandidateResolver {
3232

33+
/**
34+
* Shared instance of {@code SimpleAutowireCandidateResolver}.
35+
* @since 5.2.7
36+
*/
37+
public static final SimpleAutowireCandidateResolver INSTANCE = new SimpleAutowireCandidateResolver();
38+
39+
3340
@Override
3441
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
3542
return bdHolder.getBeanDefinition().isAutowireCandidate();
@@ -40,6 +47,11 @@ public boolean isRequired(DependencyDescriptor descriptor) {
4047
return descriptor.isRequired();
4148
}
4249

50+
@Override
51+
public boolean hasQualifier(DependencyDescriptor descriptor) {
52+
return false;
53+
}
54+
4355
@Override
4456
@Nullable
4557
public Object getSuggestedValue(DependencyDescriptor descriptor) {
@@ -52,4 +64,13 @@ public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor,
5264
return null;
5365
}
5466

67+
/**
68+
* This implementation returns {@code this} as-is.
69+
* @see #INSTANCE
70+
*/
71+
@Override
72+
public AutowireCandidateResolver cloneIfNecessary() {
73+
return this;
74+
}
75+
5576
}

0 commit comments

Comments
 (0)