1919import  java .beans .PropertyDescriptor ;
2020import  java .lang .reflect .Field ;
2121import  java .util .Arrays ;
22+ import  java .util .Collection ;
2223import  java .util .HashMap ;
2324import  java .util .LinkedHashMap ;
2425import  java .util .LinkedHashSet ;
@@ -85,14 +86,14 @@ public class MockitoPostProcessor extends InstantiationAwareBeanPostProcessorAda
8586			.getQualifiedAttributeName (ConfigurationClassPostProcessor .class ,
8687					"configurationClass" );
8788
89+ 	private  static  final  BeanNameGenerator  beanNameGenerator  = new  DefaultBeanNameGenerator ();
90+ 
8891	private  final  Set <Definition > definitions ;
8992
9093	private  ClassLoader  classLoader ;
9194
9295	private  BeanFactory  beanFactory ;
9396
94- 	private  final  BeanNameGenerator  beanNameGenerator  = new  DefaultBeanNameGenerator ();
95- 
9697	private  final  MockitoBeans  mockitoBeans  = new  MockitoBeans ();
9798
9899	private  Map <Definition , String > beanNameRegistry  = new  HashMap <>();
@@ -183,13 +184,13 @@ private void registerMock(ConfigurableListableBeanFactory beanFactory,
183184		RootBeanDefinition  beanDefinition  = createBeanDefinition (definition );
184185		String  beanName  = getBeanName (beanFactory , registry , definition , beanDefinition );
185186		String  transformedBeanName  = BeanFactoryUtils .transformedBeanName (beanName );
186- 		beanDefinition .getConstructorArgumentValues ().addIndexedArgumentValue (1 ,
187- 				beanName );
188187		if  (registry .containsBeanDefinition (transformedBeanName )) {
188+ 			BeanDefinition  existing  = registry .getBeanDefinition (transformedBeanName );
189+ 			copyBeanDefinitionDetails (existing , beanDefinition );
189190			registry .removeBeanDefinition (transformedBeanName );
190191		}
191192		registry .registerBeanDefinition (transformedBeanName , beanDefinition );
192- 		Object  mock  = createMock (definition ,  beanName );
193+ 		Object  mock  = definition . createMock (beanName  +  " bean" );
193194		beanFactory .registerSingleton (transformedBeanName , mock );
194195		this .mockitoBeans .add (mock );
195196		this .beanNameRegistry .put (definition , beanName );
@@ -202,84 +203,79 @@ private RootBeanDefinition createBeanDefinition(MockDefinition mockDefinition) {
202203		RootBeanDefinition  definition  = new  RootBeanDefinition (
203204				mockDefinition .getTypeToMock ().resolve ());
204205		definition .setTargetType (mockDefinition .getTypeToMock ());
205- 		definition .setFactoryBeanName (BEAN_NAME );
206- 		definition .setFactoryMethodName ("createMock" );
207- 		definition .getConstructorArgumentValues ().addIndexedArgumentValue (0 ,
208- 				mockDefinition );
209206		if  (mockDefinition .getQualifier () != null ) {
210207			mockDefinition .getQualifier ().applyTo (definition );
211208		}
212209		return  definition ;
213210	}
214211
215- 	/** 
216- 	 * Factory method used by defined beans to actually create the mock. 
217- 	 * @param mockDefinition the mock definition 
218- 	 * @param name the bean name 
219- 	 * @return the mock instance 
220- 	 */ 
221- 	protected  final  Object  createMock (MockDefinition  mockDefinition , String  name ) {
222- 		return  mockDefinition .createMock (name  + " bean" );
223- 	}
224- 
225212	private  String  getBeanName (ConfigurableListableBeanFactory  beanFactory ,
226213			BeanDefinitionRegistry  registry , MockDefinition  mockDefinition ,
227214			RootBeanDefinition  beanDefinition ) {
228215		if  (StringUtils .hasLength (mockDefinition .getName ())) {
229216			return  mockDefinition .getName ();
230217		}
231- 		Set <String > existingBeans  = findCandidateBeans (beanFactory , mockDefinition );
218+ 		Set <String > existingBeans  = getExistingBeans (beanFactory ,
219+ 				mockDefinition .getTypeToMock (), mockDefinition .getQualifier ());
232220		if  (existingBeans .isEmpty ()) {
233- 			return  this .beanNameGenerator .generateBeanName (beanDefinition , registry );
221+ 			return  MockitoPostProcessor .beanNameGenerator .generateBeanName (beanDefinition ,
222+ 					registry );
234223		}
235224		if  (existingBeans .size () == 1 ) {
236225			return  existingBeans .iterator ().next ();
237226		}
227+ 		String  primaryCandidate  = determinePrimaryCandidate (registry , existingBeans ,
228+ 				mockDefinition .getTypeToMock ());
229+ 		if  (primaryCandidate  != null ) {
230+ 			return  primaryCandidate ;
231+ 		}
238232		throw  new  IllegalStateException (
239233				"Unable to register mock bean "  + mockDefinition .getTypeToMock ()
240234						+ " expected a single matching bean to replace but found " 
241235						+ existingBeans );
242236	}
243237
238+ 	private  void  copyBeanDefinitionDetails (BeanDefinition  from , RootBeanDefinition  to ) {
239+ 		to .setPrimary (from .isPrimary ());
240+ 	}
241+ 
244242	private  void  registerSpy (ConfigurableListableBeanFactory  beanFactory ,
245- 			BeanDefinitionRegistry  registry , SpyDefinition  definition , Field  field ) {
246- 		String [] existingBeans  = getExistingBeans (beanFactory , definition .getTypeToSpy ());
243+ 			BeanDefinitionRegistry  registry , SpyDefinition  spyDefinition , Field  field ) {
244+ 		Set <String > existingBeans  = getExistingBeans (beanFactory ,
245+ 				spyDefinition .getTypeToSpy (), spyDefinition .getQualifier ());
247246		if  (ObjectUtils .isEmpty (existingBeans )) {
248- 			createSpy (registry , definition , field );
247+ 			createSpy (registry , spyDefinition , field );
249248		}
250249		else  {
251- 			registerSpies (registry , definition , field , existingBeans );
250+ 			registerSpies (registry , spyDefinition , field , existingBeans );
252251		}
253252	}
254253
255- 	private  Set <String > findCandidateBeans (ConfigurableListableBeanFactory  beanFactory ,
256- 			MockDefinition  mockDefinition ) {
257- 		QualifierDefinition  qualifier  = mockDefinition .getQualifier ();
254+ 	private  Set <String > getExistingBeans (ConfigurableListableBeanFactory  beanFactory ,
255+ 			ResolvableType  type , QualifierDefinition  qualifier ) {
258256		Set <String > candidates  = new  TreeSet <>();
259- 		for  (String  candidate  : getExistingBeans (beanFactory ,
260- 				mockDefinition .getTypeToMock ())) {
257+ 		for  (String  candidate  : getExistingBeans (beanFactory , type )) {
261258			if  (qualifier  == null  || qualifier .matches (beanFactory , candidate )) {
262259				candidates .add (candidate );
263260			}
264261		}
265262		return  candidates ;
266263	}
267264
268- 	private  String []  getExistingBeans (ConfigurableListableBeanFactory  beanFactory ,
265+ 	private  Set < String >  getExistingBeans (ConfigurableListableBeanFactory  beanFactory ,
269266			ResolvableType  type ) {
270267		Set <String > beans  = new  LinkedHashSet <>(
271268				Arrays .asList (beanFactory .getBeanNamesForType (type )));
272- 		String  resolvedTypeName  = type .resolve (Object .class ).getName ();
269+ 		String  typeName  = type .resolve (Object .class ).getName ();
273270		for  (String  beanName  : beanFactory .getBeanNamesForType (FactoryBean .class )) {
274271			beanName  = BeanFactoryUtils .transformedBeanName (beanName );
275272			BeanDefinition  beanDefinition  = beanFactory .getBeanDefinition (beanName );
276- 			if  (resolvedTypeName 
277- 					.equals (beanDefinition .getAttribute (FACTORY_BEAN_OBJECT_TYPE ))) {
273+ 			if  (typeName .equals (beanDefinition .getAttribute (FACTORY_BEAN_OBJECT_TYPE ))) {
278274				beans .add (beanName );
279275			}
280276		}
281277		beans .removeIf (this ::isScopedTarget );
282- 		return  StringUtils . toStringArray ( beans ) ;
278+ 		return  beans ;
283279	}
284280
285281	private  boolean  isScopedTarget (String  beanName ) {
@@ -291,49 +287,49 @@ private boolean isScopedTarget(String beanName) {
291287		}
292288	}
293289
294- 	private  void  createSpy (BeanDefinitionRegistry  registry , SpyDefinition  definition ,
290+ 	private  void  createSpy (BeanDefinitionRegistry  registry , SpyDefinition  spyDefinition ,
295291			Field  field ) {
296292		RootBeanDefinition  beanDefinition  = new  RootBeanDefinition (
297- 				definition .getTypeToSpy ().resolve ());
298- 		String  beanName  = this .beanNameGenerator . generateBeanName ( beanDefinition , 
299- 				registry );
293+ 				spyDefinition .getTypeToSpy ().resolve ());
294+ 		String  beanName  = MockitoPostProcessor .beanNameGenerator 
295+ 				. generateBeanName ( beanDefinition ,  registry );
300296		registry .registerBeanDefinition (beanName , beanDefinition );
301- 		registerSpy (definition , field , beanName );
297+ 		registerSpy (spyDefinition , field , beanName );
302298	}
303299
304- 	private  void  registerSpies (BeanDefinitionRegistry  registry ,  SpyDefinition   definition , 
305- 			Field  field , String []  existingBeans ) {
300+ 	private  void  registerSpies (BeanDefinitionRegistry  registry ,
301+ 			SpyDefinition   spyDefinition ,  Field  field , Collection < String >  existingBeans ) {
306302		try  {
307- 			registerSpy ( definition ,  field , 
308- 					 determineBeanName ( existingBeans ,  definition ,  registry ) );
303+ 			String   beanName  =  determineBeanName ( existingBeans ,  spyDefinition ,  registry ); 
304+ 			registerSpy ( spyDefinition ,  field ,  beanName );
309305		}
310306		catch  (RuntimeException  ex ) {
311307			throw  new  IllegalStateException (
312- 					"Unable to register spy bean "  + definition .getTypeToSpy (), ex );
308+ 					"Unable to register spy bean "  + spyDefinition .getTypeToSpy (), ex );
313309		}
314310	}
315311
316- 	private  String  determineBeanName (String []  existingBeans ,  SpyDefinition   definition ,
317- 			BeanDefinitionRegistry  registry ) {
312+ 	private  String  determineBeanName (Collection < String >  existingBeans ,
313+ 			SpyDefinition   definition ,  BeanDefinitionRegistry  registry ) {
318314		if  (StringUtils .hasText (definition .getName ())) {
319315			return  definition .getName ();
320316		}
321- 		if  (existingBeans .length  == 1 ) {
322- 			return  existingBeans [ 0 ] ;
317+ 		if  (existingBeans .size ()  == 1 ) {
318+ 			return  existingBeans . iterator (). next () ;
323319		}
324320		return  determinePrimaryCandidate (registry , existingBeans ,
325321				definition .getTypeToSpy ());
326322	}
327323
328324	private  String  determinePrimaryCandidate (BeanDefinitionRegistry  registry ,
329- 			String []  candidateBeanNames , ResolvableType  type ) {
325+ 			Collection < String >  candidateBeanNames , ResolvableType  type ) {
330326		String  primaryBeanName  = null ;
331327		for  (String  candidateBeanName  : candidateBeanNames ) {
332328			BeanDefinition  beanDefinition  = registry .getBeanDefinition (candidateBeanName );
333329			if  (beanDefinition .isPrimary ()) {
334330				if  (primaryBeanName  != null ) {
335331					throw  new  NoUniqueBeanDefinitionException (type .resolve (),
336- 							candidateBeanNames .length ,
332+ 							candidateBeanNames .size () ,
337333							"more than one 'primary' bean found among candidates: " 
338334									+ Arrays .asList (candidateBeanNames ));
339335				}
@@ -351,7 +347,7 @@ private void registerSpy(SpyDefinition definition, Field field, String beanName)
351347		}
352348	}
353349
354- 	protected  Object  createSpyIfNecessary (Object  bean , String  beanName )
350+ 	protected  final   Object  createSpyIfNecessary (Object  bean , String  beanName )
355351			throws  BeansException  {
356352		SpyDefinition  definition  = this .spies .get (beanName );
357353		if  (definition  != null ) {
@@ -480,7 +476,7 @@ public int getOrder() {
480476		@ Override 
481477		public  Object  getEarlyBeanReference (Object  bean , String  beanName )
482478				throws  BeansException  {
483- 			return  createSpyIfNecessary (bean , beanName );
479+ 			return  this . mockitoPostProcessor . createSpyIfNecessary (bean , beanName );
484480		}
485481
486482		@ Override 
@@ -489,10 +485,6 @@ public Object postProcessAfterInitialization(Object bean, String beanName)
489485			if  (bean  instanceof  FactoryBean ) {
490486				return  bean ;
491487			}
492- 			return  createSpyIfNecessary (bean , beanName );
493- 		}
494- 
495- 		private  Object  createSpyIfNecessary (Object  bean , String  beanName ) {
496488			return  this .mockitoPostProcessor .createSpyIfNecessary (bean , beanName );
497489		}
498490
0 commit comments