31
31
import org .springframework .beans .factory .config .BeanDefinition ;
32
32
import org .springframework .beans .factory .config .BeanFactoryPostProcessor ;
33
33
import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
34
+ import org .springframework .beans .factory .config .DependencyDescriptor ;
34
35
import org .springframework .beans .factory .config .SmartInstantiationAwareBeanPostProcessor ;
35
36
import org .springframework .beans .factory .support .BeanDefinitionRegistry ;
36
37
import org .springframework .beans .factory .support .RootBeanDefinition ;
@@ -127,28 +128,34 @@ private void registerReplaceDefinition(ConfigurableListableBeanFactory beanFacto
127
128
128
129
RootBeanDefinition beanDefinition = createBeanDefinition (overrideMetadata );
129
130
String beanName = overrideMetadata .getBeanName ();
131
+ BeanDefinition existingBeanDefinition = null ;
130
132
if (beanName == null ) {
131
- final String [] candidates = beanFactory . getBeanNamesForType ( overrideMetadata . getBeanType () );
132
- if (candidates .length != 1 ) {
133
+ Set < String > candidates = getExistingBeanNamesByType ( beanFactory , overrideMetadata , true );
134
+ if (candidates .size () != 1 ) {
133
135
Field f = overrideMetadata .getField ();
134
136
throw new IllegalStateException ("Unable to select a bean definition to override, " +
135
- candidates .length + " bean definitions found of type " + overrideMetadata .getBeanType () +
137
+ candidates .size () + " bean definitions found of type " + overrideMetadata .getBeanType () +
136
138
" (as required by annotated field '" + f .getDeclaringClass ().getSimpleName () +
137
139
"." + f .getName () + "')" );
138
140
}
139
- beanName = candidates [0 ];
141
+ beanName = candidates .iterator ().next ();
142
+ existingBeanDefinition = beanFactory .getBeanDefinition (beanName );
143
+ }
144
+ else {
145
+ Set <String > candidates = getExistingBeanNamesByType (beanFactory , overrideMetadata , false );
146
+ if (candidates .contains (beanName )) {
147
+ existingBeanDefinition = beanFactory .getBeanDefinition (beanName );
148
+ }
149
+ else if (enforceExistingDefinition ) {
150
+ throw new IllegalStateException ("Unable to override bean '" + beanName + "'; there is no" +
151
+ " bean definition to replace with that name of type " + overrideMetadata .getBeanType ());
152
+ }
140
153
}
141
154
142
- BeanDefinition existingBeanDefinition = null ;
143
- if (beanFactory .containsBeanDefinition (beanName )) {
144
- existingBeanDefinition = beanFactory .getBeanDefinition (beanName );
155
+ if (existingBeanDefinition != null ) {
145
156
copyBeanDefinitionDetails (existingBeanDefinition , beanDefinition );
146
157
registry .removeBeanDefinition (beanName );
147
158
}
148
- else if (enforceExistingDefinition ) {
149
- throw new IllegalStateException ("Unable to override bean '" + beanName + "'; there is no" +
150
- " bean definition to replace with that name" );
151
- }
152
159
registry .registerBeanDefinition (beanName , beanDefinition );
153
160
154
161
Object override = overrideMetadata .createOverride (beanName , existingBeanDefinition , null );
@@ -171,33 +178,40 @@ else if (enforceExistingDefinition) {
171
178
* phase.
172
179
*/
173
180
private void registerWrapBean (ConfigurableListableBeanFactory beanFactory , OverrideMetadata metadata ) {
174
- Set <String > existingBeanNames = getExistingBeanNames (beanFactory , metadata .getBeanType ());
175
181
String beanName = metadata .getBeanName ();
176
182
if (beanName == null ) {
177
- if (existingBeanNames .size () != 1 ) {
183
+ Set <String > candidateNames = getExistingBeanNamesByType (beanFactory , metadata , true );
184
+ if (candidateNames .size () != 1 ) {
178
185
Field f = metadata .getField ();
179
186
throw new IllegalStateException ("Unable to select a bean to override by wrapping, " +
180
- existingBeanNames .size () + " bean instances found of type " + metadata .getBeanType () +
187
+ candidateNames .size () + " bean instances found of type " + metadata .getBeanType () +
181
188
" (as required by annotated field '" + f .getDeclaringClass ().getSimpleName () +
182
189
"." + f .getName () + "')" );
183
190
}
184
- beanName = existingBeanNames .iterator ().next ();
191
+ beanName = candidateNames .iterator ().next ();
185
192
}
186
- else if (!existingBeanNames .contains (beanName )) {
187
- throw new IllegalStateException ("Unable to override bean '" + beanName + "' by wrapping; " +
188
- "there is no existing bean instance with that name of type " + metadata .getBeanType ());
193
+ else {
194
+ Set <String > candidates = getExistingBeanNamesByType (beanFactory , metadata , false );
195
+ if (!candidates .contains (beanName )) {
196
+ throw new IllegalStateException ("Unable to override bean '" + beanName + "' by wrapping; there is no" +
197
+ " existing bean instance with that name of type " + metadata .getBeanType ());
198
+ }
189
199
}
190
200
this .overrideRegistrar .markWrapEarly (metadata , beanName );
191
201
this .overrideRegistrar .registerNameForMetadata (metadata , beanName );
192
202
}
193
203
194
- private RootBeanDefinition createBeanDefinition (OverrideMetadata metadata ) {
204
+ RootBeanDefinition createBeanDefinition (OverrideMetadata metadata ) {
195
205
RootBeanDefinition definition = new RootBeanDefinition ();
196
206
definition .setTargetType (metadata .getBeanType ());
207
+ definition .setQualifiedElement (metadata .getField ());
197
208
return definition ;
198
209
}
199
210
200
- private Set <String > getExistingBeanNames (ConfigurableListableBeanFactory beanFactory , ResolvableType resolvableType ) {
211
+ private Set <String > getExistingBeanNamesByType (ConfigurableListableBeanFactory beanFactory , OverrideMetadata metadata ,
212
+ boolean checkAutowiredCandidate ) {
213
+
214
+ ResolvableType resolvableType = metadata .getBeanType ();
201
215
Set <String > beans = new LinkedHashSet <>(
202
216
Arrays .asList (beanFactory .getBeanNamesForType (resolvableType , true , false )));
203
217
Class <?> type = resolvableType .resolve (Object .class );
@@ -209,7 +223,14 @@ private Set<String> getExistingBeanNames(ConfigurableListableBeanFactory beanFac
209
223
beans .add (beanName );
210
224
}
211
225
}
212
- beans .removeIf (ScopedProxyUtils ::isScopedTarget );
226
+ if (checkAutowiredCandidate ) {
227
+ DependencyDescriptor descriptor = new DependencyDescriptor (metadata .getField (), true );
228
+ beans .removeIf (beanName -> ScopedProxyUtils .isScopedTarget (beanName ) ||
229
+ !beanFactory .isAutowireCandidate (beanName , descriptor ));
230
+ }
231
+ else {
232
+ beans .removeIf (ScopedProxyUtils ::isScopedTarget );
233
+ }
213
234
return beans ;
214
235
}
215
236
0 commit comments