View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.beans.factory.annotation;
18  
19  import java.io.Serializable;
20  import java.lang.annotation.ElementType;
21  import java.lang.annotation.Retention;
22  import java.lang.annotation.RetentionPolicy;
23  import java.lang.annotation.Target;
24  import java.lang.reflect.InvocationHandler;
25  import java.lang.reflect.Method;
26  import java.lang.reflect.Proxy;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.concurrent.Callable;
30  
31  import org.junit.Ignore;
32  import org.junit.Test;
33  import org.mockito.Mockito;
34  
35  import org.springframework.beans.factory.BeanCreationException;
36  import org.springframework.beans.factory.BeanFactory;
37  import org.springframework.beans.factory.FactoryBean;
38  import org.springframework.beans.factory.ObjectFactory;
39  import org.springframework.beans.factory.UnsatisfiedDependencyException;
40  import org.springframework.beans.factory.config.BeanDefinition;
41  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
42  import org.springframework.beans.factory.config.TypedStringValue;
43  import org.springframework.beans.factory.support.AutowireCandidateQualifier;
44  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
45  import org.springframework.beans.factory.support.GenericBeanDefinition;
46  import org.springframework.beans.factory.support.RootBeanDefinition;
47  import org.springframework.core.Ordered;
48  import org.springframework.core.annotation.AnnotationAwareOrderComparator;
49  import org.springframework.core.annotation.Order;
50  import org.springframework.tests.sample.beans.ITestBean;
51  import org.springframework.tests.sample.beans.IndexedTestBean;
52  import org.springframework.tests.sample.beans.NestedTestBean;
53  import org.springframework.tests.sample.beans.TestBean;
54  import org.springframework.util.SerializationTestUtils;
55  
56  import static org.junit.Assert.*;
57  
58  /**
59   * @author Juergen Hoeller
60   * @author Mark Fisher
61   * @author Sam Brannen
62   * @author Chris Beams
63   * @author Stephane Nicoll
64   */
65  public class AutowiredAnnotationBeanPostProcessorTests {
66  
67  	@Test
68  	public void testIncompleteBeanDefinition() {
69  		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
70  		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
71  		bpp.setBeanFactory(bf);
72  		bf.addBeanPostProcessor(bpp);
73  		bf.registerBeanDefinition("testBean", new GenericBeanDefinition());
74  		try {
75  			bf.getBean("testBean");
76  		}
77  		catch (BeanCreationException ex) {
78  			assertTrue(ex.getRootCause() instanceof IllegalStateException);
79  		}
80  	}
81  
82  	@Test
83  	public void testResourceInjection() {
84  		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
85  		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
86  		bpp.setBeanFactory(bf);
87  		bf.addBeanPostProcessor(bpp);
88  		RootBeanDefinition bd = new RootBeanDefinition(ResourceInjectionBean.class);
89  		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
90  		bf.registerBeanDefinition("annotatedBean", bd);
91  		TestBean tb = new TestBean();
92  		bf.registerSingleton("testBean", tb);
93  
94  		ResourceInjectionBean bean = (ResourceInjectionBean) bf.getBean("annotatedBean");
95  		assertSame(tb, bean.getTestBean());
96  		assertSame(tb, bean.getTestBean2());
97  
98  		bean = (ResourceInjectionBean) bf.getBean("annotatedBean");
99  		assertSame(tb, bean.getTestBean());
100 		assertSame(tb, bean.getTestBean2());
101 	}
102 
103 	@Test
104 	public void testExtendedResourceInjection() {
105 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
106 		bf.registerResolvableDependency(BeanFactory.class, bf);
107 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
108 		bpp.setBeanFactory(bf);
109 		bf.addBeanPostProcessor(bpp);
110 		RootBeanDefinition bd = new RootBeanDefinition(TypedExtendedResourceInjectionBean.class);
111 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
112 		bf.registerBeanDefinition("annotatedBean", bd);
113 		TestBean tb = new TestBean();
114 		bf.registerSingleton("testBean", tb);
115 		NestedTestBean ntb = new NestedTestBean();
116 		bf.registerSingleton("nestedTestBean", ntb);
117 
118 		TypedExtendedResourceInjectionBean bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
119 		assertSame(tb, bean.getTestBean());
120 		assertSame(tb, bean.getTestBean2());
121 		assertSame(tb, bean.getTestBean3());
122 		assertSame(tb, bean.getTestBean4());
123 		assertSame(ntb, bean.getNestedTestBean());
124 		assertSame(bf, bean.getBeanFactory());
125 
126 		bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
127 		assertSame(tb, bean.getTestBean());
128 		assertSame(tb, bean.getTestBean2());
129 		assertSame(tb, bean.getTestBean3());
130 		assertSame(tb, bean.getTestBean4());
131 		assertSame(ntb, bean.getNestedTestBean());
132 		assertSame(bf, bean.getBeanFactory());
133 
134 		String[] depBeans = bf.getDependenciesForBean("annotatedBean");
135 		assertEquals(2, depBeans.length);
136 		assertEquals("testBean", depBeans[0]);
137 		assertEquals("nestedTestBean", depBeans[1]);
138 	}
139 
140 	@Test
141 	public void testExtendedResourceInjectionWithOverriding() {
142 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
143 		bf.registerResolvableDependency(BeanFactory.class, bf);
144 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
145 		bpp.setBeanFactory(bf);
146 		bf.addBeanPostProcessor(bpp);
147 		RootBeanDefinition annotatedBd = new RootBeanDefinition(TypedExtendedResourceInjectionBean.class);
148 		TestBean tb2 = new TestBean();
149 		annotatedBd.getPropertyValues().add("testBean2", tb2);
150 		bf.registerBeanDefinition("annotatedBean", annotatedBd);
151 		TestBean tb = new TestBean();
152 		bf.registerSingleton("testBean", tb);
153 		NestedTestBean ntb = new NestedTestBean();
154 		bf.registerSingleton("nestedTestBean", ntb);
155 
156 		TypedExtendedResourceInjectionBean bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
157 		assertSame(tb, bean.getTestBean());
158 		assertSame(tb2, bean.getTestBean2());
159 		assertSame(tb, bean.getTestBean3());
160 		assertSame(tb, bean.getTestBean4());
161 		assertSame(ntb, bean.getNestedTestBean());
162 		assertSame(bf, bean.getBeanFactory());
163 		bf.destroySingletons();
164 	}
165 
166 	@Test
167 	public void testExtendedResourceInjectionWithSkippedOverriddenMethods() {
168 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
169 		bf.registerResolvableDependency(BeanFactory.class, bf);
170 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
171 		bpp.setBeanFactory(bf);
172 		bf.addBeanPostProcessor(bpp);
173 		RootBeanDefinition annotatedBd = new RootBeanDefinition(OverriddenExtendedResourceInjectionBean.class);
174 		bf.registerBeanDefinition("annotatedBean", annotatedBd);
175 		TestBean tb = new TestBean();
176 		bf.registerSingleton("testBean", tb);
177 		NestedTestBean ntb = new NestedTestBean();
178 		bf.registerSingleton("nestedTestBean", ntb);
179 
180 		OverriddenExtendedResourceInjectionBean bean = (OverriddenExtendedResourceInjectionBean) bf.getBean("annotatedBean");
181 		assertSame(tb, bean.getTestBean());
182 		assertNull(bean.getTestBean2());
183 		assertSame(tb, bean.getTestBean3());
184 		assertSame(tb, bean.getTestBean4());
185 		assertSame(ntb, bean.getNestedTestBean());
186 		assertNull(bean.getBeanFactory());
187 		assertTrue(bean.baseInjected);
188 		assertTrue(bean.subInjected);
189 		bf.destroySingletons();
190 	}
191 
192 	@Test
193 	public void testExtendedResourceInjectionWithAtRequired() {
194 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
195 		bf.registerResolvableDependency(BeanFactory.class, bf);
196 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
197 		bpp.setBeanFactory(bf);
198 		bf.addBeanPostProcessor(bpp);
199 		bf.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
200 		RootBeanDefinition bd = new RootBeanDefinition(TypedExtendedResourceInjectionBean.class);
201 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
202 		bf.registerBeanDefinition("annotatedBean", bd);
203 		TestBean tb = new TestBean();
204 		bf.registerSingleton("testBean", tb);
205 		NestedTestBean ntb = new NestedTestBean();
206 		bf.registerSingleton("nestedTestBean", ntb);
207 
208 		TypedExtendedResourceInjectionBean bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
209 		assertSame(tb, bean.getTestBean());
210 		assertSame(tb, bean.getTestBean2());
211 		assertSame(tb, bean.getTestBean3());
212 		assertSame(tb, bean.getTestBean4());
213 		assertSame(ntb, bean.getNestedTestBean());
214 		assertSame(bf, bean.getBeanFactory());
215 	}
216 
217 	@Test
218 	public void testOptionalResourceInjection() {
219 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
220 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
221 		bpp.setBeanFactory(bf);
222 		bf.addBeanPostProcessor(bpp);
223 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
224 		TestBean tb = new TestBean();
225 		bf.registerSingleton("testBean", tb);
226 		IndexedTestBean itb = new IndexedTestBean();
227 		bf.registerSingleton("indexedTestBean", itb);
228 		NestedTestBean ntb1 = new NestedTestBean();
229 		bf.registerSingleton("nestedTestBean1", ntb1);
230 		NestedTestBean ntb2 = new NestedTestBean();
231 		bf.registerSingleton("nestedTestBean2", ntb2);
232 
233 		OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
234 		assertSame(tb, bean.getTestBean());
235 		assertSame(tb, bean.getTestBean2());
236 		assertSame(tb, bean.getTestBean3());
237 		assertSame(tb, bean.getTestBean4());
238 		assertSame(itb, bean.getIndexedTestBean());
239 		assertEquals(2, bean.getNestedTestBeans().length);
240 		assertSame(ntb1, bean.getNestedTestBeans()[0]);
241 		assertSame(ntb2, bean.getNestedTestBeans()[1]);
242 		assertEquals(2, bean.nestedTestBeansField.length);
243 		assertSame(ntb1, bean.nestedTestBeansField[0]);
244 		assertSame(ntb2, bean.nestedTestBeansField[1]);
245 		bf.destroySingletons();
246 	}
247 
248 	@Test
249 	public void testOptionalCollectionResourceInjection() {
250 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
251 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
252 		bpp.setBeanFactory(bf);
253 		bf.addBeanPostProcessor(bpp);
254 		RootBeanDefinition rbd = new RootBeanDefinition(OptionalCollectionResourceInjectionBean.class);
255 		rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
256 		bf.registerBeanDefinition("annotatedBean", rbd);
257 		TestBean tb = new TestBean();
258 		bf.registerSingleton("testBean", tb);
259 		IndexedTestBean itb = new IndexedTestBean();
260 		bf.registerSingleton("indexedTestBean", itb);
261 		NestedTestBean ntb1 = new NestedTestBean();
262 		bf.registerSingleton("nestedTestBean1", ntb1);
263 		NestedTestBean ntb2 = new NestedTestBean();
264 		bf.registerSingleton("nestedTestBean2", ntb2);
265 
266 		// Two calls to verify that caching doesn't break re-creation.
267 		OptionalCollectionResourceInjectionBean bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
268 		bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
269 		assertSame(tb, bean.getTestBean());
270 		assertSame(tb, bean.getTestBean2());
271 		assertSame(tb, bean.getTestBean3());
272 		assertSame(tb, bean.getTestBean4());
273 		assertSame(itb, bean.getIndexedTestBean());
274 		assertEquals(2, bean.getNestedTestBeans().size());
275 		assertSame(ntb1, bean.getNestedTestBeans().get(0));
276 		assertSame(ntb2, bean.getNestedTestBeans().get(1));
277 		assertEquals(2, bean.nestedTestBeansSetter.size());
278 		assertSame(ntb1, bean.nestedTestBeansSetter.get(0));
279 		assertSame(ntb2, bean.nestedTestBeansSetter.get(1));
280 		assertEquals(2, bean.nestedTestBeansField.size());
281 		assertSame(ntb1, bean.nestedTestBeansField.get(0));
282 		assertSame(ntb2, bean.nestedTestBeansField.get(1));
283 		bf.destroySingletons();
284 	}
285 
286 	@Test
287 	public void testOptionalCollectionResourceInjectionWithSingleElement() {
288 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
289 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
290 		bpp.setBeanFactory(bf);
291 		bf.addBeanPostProcessor(bpp);
292 		RootBeanDefinition rbd = new RootBeanDefinition(OptionalCollectionResourceInjectionBean.class);
293 		rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
294 		bf.registerBeanDefinition("annotatedBean", rbd);
295 		TestBean tb = new TestBean();
296 		bf.registerSingleton("testBean", tb);
297 		IndexedTestBean itb = new IndexedTestBean();
298 		bf.registerSingleton("indexedTestBean", itb);
299 		NestedTestBean ntb1 = new NestedTestBean();
300 		bf.registerSingleton("nestedTestBean1", ntb1);
301 
302 		// Two calls to verify that caching doesn't break re-creation.
303 		OptionalCollectionResourceInjectionBean bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
304 		bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
305 		assertSame(tb, bean.getTestBean());
306 		assertSame(tb, bean.getTestBean2());
307 		assertSame(tb, bean.getTestBean3());
308 		assertSame(tb, bean.getTestBean4());
309 		assertSame(itb, bean.getIndexedTestBean());
310 		assertEquals(1, bean.getNestedTestBeans().size());
311 		assertSame(ntb1, bean.getNestedTestBeans().get(0));
312 		assertEquals(1, bean.nestedTestBeansSetter.size());
313 		assertSame(ntb1, bean.nestedTestBeansSetter.get(0));
314 		assertEquals(1, bean.nestedTestBeansField.size());
315 		assertSame(ntb1, bean.nestedTestBeansField.get(0));
316 		bf.destroySingletons();
317 	}
318 
319 	@Test
320 	public void testOptionalResourceInjectionWithIncompleteDependencies() {
321 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
322 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
323 		bpp.setBeanFactory(bf);
324 		bf.addBeanPostProcessor(bpp);
325 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
326 		TestBean tb = new TestBean();
327 		bf.registerSingleton("testBean", tb);
328 
329 		OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
330 		assertSame(tb, bean.getTestBean());
331 		assertSame(tb, bean.getTestBean2());
332 		assertSame(tb, bean.getTestBean3());
333 		assertNull(bean.getTestBean4());
334 		assertNull(bean.getNestedTestBeans());
335 		bf.destroySingletons();
336 	}
337 
338 	@Test
339 	public void testOptionalResourceInjectionWithNoDependencies() {
340 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
341 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
342 		bpp.setBeanFactory(bf);
343 		bf.addBeanPostProcessor(bpp);
344 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
345 
346 		OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
347 		assertNull(bean.getTestBean());
348 		assertNull(bean.getTestBean2());
349 		assertNull(bean.getTestBean3());
350 		assertNull(bean.getTestBean4());
351 		assertNull(bean.getNestedTestBeans());
352 		bf.destroySingletons();
353 	}
354 
355 	@Test
356 	public void testOrderedResourceInjection() {
357 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
358 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
359 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
360 		bpp.setBeanFactory(bf);
361 		bf.addBeanPostProcessor(bpp);
362 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
363 		TestBean tb = new TestBean();
364 		bf.registerSingleton("testBean", tb);
365 		IndexedTestBean itb = new IndexedTestBean();
366 		bf.registerSingleton("indexedTestBean", itb);
367 		OrderedNestedTestBean ntb1 = new OrderedNestedTestBean();
368 		ntb1.setOrder(2);
369 		bf.registerSingleton("nestedTestBean1", ntb1);
370 		OrderedNestedTestBean ntb2 = new OrderedNestedTestBean();
371 		ntb2.setOrder(1);
372 		bf.registerSingleton("nestedTestBean2", ntb2);
373 
374 		OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
375 		assertSame(tb, bean.getTestBean());
376 		assertSame(tb, bean.getTestBean2());
377 		assertSame(tb, bean.getTestBean3());
378 		assertSame(tb, bean.getTestBean4());
379 		assertSame(itb, bean.getIndexedTestBean());
380 		assertEquals(2, bean.getNestedTestBeans().length);
381 		assertSame(ntb2, bean.getNestedTestBeans()[0]);
382 		assertSame(ntb1, bean.getNestedTestBeans()[1]);
383 		assertEquals(2, bean.nestedTestBeansField.length);
384 		assertSame(ntb2, bean.nestedTestBeansField[0]);
385 		assertSame(ntb1, bean.nestedTestBeansField[1]);
386 		bf.destroySingletons();
387 	}
388 
389 	@Test
390 	public void testAnnotationOrderedResourceInjection() {
391 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
392 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
393 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
394 		bpp.setBeanFactory(bf);
395 		bf.addBeanPostProcessor(bpp);
396 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
397 		TestBean tb = new TestBean();
398 		bf.registerSingleton("testBean", tb);
399 		IndexedTestBean itb = new IndexedTestBean();
400 		bf.registerSingleton("indexedTestBean", itb);
401 		FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
402 		bf.registerSingleton("nestedTestBean1", ntb1);
403 		FixedOrder1NestedTestBean ntb2 = new FixedOrder1NestedTestBean();
404 		bf.registerSingleton("nestedTestBean2", ntb2);
405 
406 		OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
407 		assertSame(tb, bean.getTestBean());
408 		assertSame(tb, bean.getTestBean2());
409 		assertSame(tb, bean.getTestBean3());
410 		assertSame(tb, bean.getTestBean4());
411 		assertSame(itb, bean.getIndexedTestBean());
412 		assertEquals(2, bean.getNestedTestBeans().length);
413 		assertSame(ntb2, bean.getNestedTestBeans()[0]);
414 		assertSame(ntb1, bean.getNestedTestBeans()[1]);
415 		assertEquals(2, bean.nestedTestBeansField.length);
416 		assertSame(ntb2, bean.nestedTestBeansField[0]);
417 		assertSame(ntb1, bean.nestedTestBeansField[1]);
418 		bf.destroySingletons();
419 	}
420 
421 	@Test
422 	public void testOrderedCollectionResourceInjection() {
423 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
424 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
425 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
426 		bpp.setBeanFactory(bf);
427 		bf.addBeanPostProcessor(bpp);
428 		RootBeanDefinition rbd = new RootBeanDefinition(OptionalCollectionResourceInjectionBean.class);
429 		rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
430 		bf.registerBeanDefinition("annotatedBean", rbd);
431 		TestBean tb = new TestBean();
432 		bf.registerSingleton("testBean", tb);
433 		IndexedTestBean itb = new IndexedTestBean();
434 		bf.registerSingleton("indexedTestBean", itb);
435 		OrderedNestedTestBean ntb1 = new OrderedNestedTestBean();
436 		ntb1.setOrder(2);
437 		bf.registerSingleton("nestedTestBean1", ntb1);
438 		OrderedNestedTestBean ntb2 = new OrderedNestedTestBean();
439 		ntb2.setOrder(1);
440 		bf.registerSingleton("nestedTestBean2", ntb2);
441 
442 		// Two calls to verify that caching doesn't break re-creation.
443 		OptionalCollectionResourceInjectionBean bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
444 		bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
445 		assertSame(tb, bean.getTestBean());
446 		assertSame(tb, bean.getTestBean2());
447 		assertSame(tb, bean.getTestBean3());
448 		assertSame(tb, bean.getTestBean4());
449 		assertSame(itb, bean.getIndexedTestBean());
450 		assertEquals(2, bean.getNestedTestBeans().size());
451 		assertSame(ntb2, bean.getNestedTestBeans().get(0));
452 		assertSame(ntb1, bean.getNestedTestBeans().get(1));
453 		assertEquals(2, bean.nestedTestBeansSetter.size());
454 		assertSame(ntb2, bean.nestedTestBeansSetter.get(0));
455 		assertSame(ntb1, bean.nestedTestBeansSetter.get(1));
456 		assertEquals(2, bean.nestedTestBeansField.size());
457 		assertSame(ntb2, bean.nestedTestBeansField.get(0));
458 		assertSame(ntb1, bean.nestedTestBeansField.get(1));
459 		bf.destroySingletons();
460 	}
461 
462 	@Test
463 	public void testAnnotationOrderedCollectionResourceInjection() {
464 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
465 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
466 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
467 		bpp.setBeanFactory(bf);
468 		bf.addBeanPostProcessor(bpp);
469 		RootBeanDefinition rbd = new RootBeanDefinition(OptionalCollectionResourceInjectionBean.class);
470 		rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
471 		bf.registerBeanDefinition("annotatedBean", rbd);
472 		TestBean tb = new TestBean();
473 		bf.registerSingleton("testBean", tb);
474 		IndexedTestBean itb = new IndexedTestBean();
475 		bf.registerSingleton("indexedTestBean", itb);
476 		FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
477 		bf.registerSingleton("nestedTestBean1", ntb1);
478 		FixedOrder1NestedTestBean ntb2 = new FixedOrder1NestedTestBean();
479 		bf.registerSingleton("nestedTestBean2", ntb2);
480 
481 		// Two calls to verify that caching doesn't break re-creation.
482 		OptionalCollectionResourceInjectionBean bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
483 		bean = (OptionalCollectionResourceInjectionBean) bf.getBean("annotatedBean");
484 		assertSame(tb, bean.getTestBean());
485 		assertSame(tb, bean.getTestBean2());
486 		assertSame(tb, bean.getTestBean3());
487 		assertSame(tb, bean.getTestBean4());
488 		assertSame(itb, bean.getIndexedTestBean());
489 		assertEquals(2, bean.getNestedTestBeans().size());
490 		assertSame(ntb2, bean.getNestedTestBeans().get(0));
491 		assertSame(ntb1, bean.getNestedTestBeans().get(1));
492 		assertEquals(2, bean.nestedTestBeansSetter.size());
493 		assertSame(ntb2, bean.nestedTestBeansSetter.get(0));
494 		assertSame(ntb1, bean.nestedTestBeansSetter.get(1));
495 		assertEquals(2, bean.nestedTestBeansField.size());
496 		assertSame(ntb2, bean.nestedTestBeansField.get(0));
497 		assertSame(ntb1, bean.nestedTestBeansField.get(1));
498 		bf.destroySingletons();
499 	}
500 
501 	@Test
502 	public void testConstructorResourceInjection() {
503 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
504 		bf.registerResolvableDependency(BeanFactory.class, bf);
505 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
506 		bpp.setBeanFactory(bf);
507 		bf.addBeanPostProcessor(bpp);
508 		RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
509 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
510 		bf.registerBeanDefinition("annotatedBean", bd);
511 		TestBean tb = new TestBean();
512 		bf.registerSingleton("testBean", tb);
513 		NestedTestBean ntb = new NestedTestBean();
514 		bf.registerSingleton("nestedTestBean", ntb);
515 
516 		ConstructorResourceInjectionBean bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
517 		assertSame(tb, bean.getTestBean());
518 		assertSame(tb, bean.getTestBean2());
519 		assertSame(tb, bean.getTestBean3());
520 		assertSame(tb, bean.getTestBean4());
521 		assertSame(ntb, bean.getNestedTestBean());
522 		assertSame(bf, bean.getBeanFactory());
523 
524 		bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
525 		assertSame(tb, bean.getTestBean());
526 		assertSame(tb, bean.getTestBean2());
527 		assertSame(tb, bean.getTestBean3());
528 		assertSame(tb, bean.getTestBean4());
529 		assertSame(ntb, bean.getNestedTestBean());
530 		assertSame(bf, bean.getBeanFactory());
531 	}
532 
533 	@Test
534 	public void testConstructorResourceInjectionWithMultipleCandidates() {
535 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
536 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
537 		bpp.setBeanFactory(bf);
538 		bf.addBeanPostProcessor(bpp);
539 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorsResourceInjectionBean.class));
540 		TestBean tb = new TestBean();
541 		bf.registerSingleton("testBean", tb);
542 		NestedTestBean ntb1 = new NestedTestBean();
543 		bf.registerSingleton("nestedTestBean1", ntb1);
544 		NestedTestBean ntb2 = new NestedTestBean();
545 		bf.registerSingleton("nestedTestBean2", ntb2);
546 
547 		ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
548 		assertNull(bean.getTestBean3());
549 		assertSame(tb, bean.getTestBean4());
550 		assertEquals(2, bean.getNestedTestBeans().length);
551 		assertSame(ntb1, bean.getNestedTestBeans()[0]);
552 		assertSame(ntb2, bean.getNestedTestBeans()[1]);
553 		bf.destroySingletons();
554 	}
555 
556 	@Test
557 	public void testConstructorResourceInjectionWithNoCandidatesAndNoFallback() {
558 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
559 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
560 		bpp.setBeanFactory(bf);
561 		bf.addBeanPostProcessor(bpp);
562 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorWithoutFallbackBean.class));
563 
564 		try {
565 			bf.getBean("annotatedBean");
566 			fail("Should have thrown UnsatisfiedDependencyException");
567 		}
568 		catch (UnsatisfiedDependencyException ex) {
569 			// expected
570 		}
571 	}
572 
573 	@Test
574 	public void testConstructorResourceInjectionWithMultipleCandidatesAsCollection() {
575 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
576 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
577 		bpp.setBeanFactory(bf);
578 		bf.addBeanPostProcessor(bpp);
579 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(
580 				ConstructorsCollectionResourceInjectionBean.class));
581 		TestBean tb = new TestBean();
582 		bf.registerSingleton("testBean", tb);
583 		NestedTestBean ntb1 = new NestedTestBean();
584 		bf.registerSingleton("nestedTestBean1", ntb1);
585 		NestedTestBean ntb2 = new NestedTestBean();
586 		bf.registerSingleton("nestedTestBean2", ntb2);
587 
588 		ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
589 		assertNull(bean.getTestBean3());
590 		assertSame(tb, bean.getTestBean4());
591 		assertEquals(2, bean.getNestedTestBeans().size());
592 		assertSame(ntb1, bean.getNestedTestBeans().get(0));
593 		assertSame(ntb2, bean.getNestedTestBeans().get(1));
594 		bf.destroySingletons();
595 	}
596 
597 	@Test
598 	public void testConstructorResourceInjectionWithMultipleOrderedCandidates() {
599 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
600 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
601 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
602 		bpp.setBeanFactory(bf);
603 		bf.addBeanPostProcessor(bpp);
604 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorsResourceInjectionBean.class));
605 		TestBean tb = new TestBean();
606 		bf.registerSingleton("testBean", tb);
607 		FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
608 		bf.registerSingleton("nestedTestBean1", ntb1);
609 		FixedOrder1NestedTestBean ntb2 = new FixedOrder1NestedTestBean();
610 		bf.registerSingleton("nestedTestBean2", ntb2);
611 
612 		ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
613 		assertNull(bean.getTestBean3());
614 		assertSame(tb, bean.getTestBean4());
615 		assertEquals(2, bean.getNestedTestBeans().length);
616 		assertSame(ntb2, bean.getNestedTestBeans()[0]);
617 		assertSame(ntb1, bean.getNestedTestBeans()[1]);
618 		bf.destroySingletons();
619 	}
620 
621 	@Test
622 	public void testConstructorResourceInjectionWithMultipleCandidatesAsOrderedCollection() {
623 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
624 		bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
625 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
626 		bpp.setBeanFactory(bf);
627 		bf.addBeanPostProcessor(bpp);
628 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(
629 				ConstructorsCollectionResourceInjectionBean.class));
630 		TestBean tb = new TestBean();
631 		bf.registerSingleton("testBean", tb);
632 		FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
633 		bf.registerSingleton("nestedTestBean1", ntb1);
634 		FixedOrder1NestedTestBean ntb2 = new FixedOrder1NestedTestBean();
635 		bf.registerSingleton("nestedTestBean2", ntb2);
636 
637 		ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
638 		assertNull(bean.getTestBean3());
639 		assertSame(tb, bean.getTestBean4());
640 		assertEquals(2, bean.getNestedTestBeans().size());
641 		assertSame(ntb2, bean.getNestedTestBeans().get(0));
642 		assertSame(ntb1, bean.getNestedTestBeans().get(1));
643 		bf.destroySingletons();
644 	}
645 
646 	@Test
647 	public void testConstructorResourceInjectionWithMultipleCandidatesAndFallback() {
648 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
649 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
650 		bpp.setBeanFactory(bf);
651 		bf.addBeanPostProcessor(bpp);
652 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorsResourceInjectionBean.class));
653 		TestBean tb = new TestBean();
654 		bf.registerSingleton("testBean", tb);
655 
656 		ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
657 		assertSame(tb, bean.getTestBean3());
658 		assertNull(bean.getTestBean4());
659 		bf.destroySingletons();
660 	}
661 
662 	@Test
663 	public void testConstructorResourceInjectionWithMultipleCandidatesAndDefaultFallback() {
664 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
665 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
666 		bpp.setBeanFactory(bf);
667 		bf.addBeanPostProcessor(bpp);
668 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorsResourceInjectionBean.class));
669 
670 		ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
671 		assertNull(bean.getTestBean3());
672 		assertNull(bean.getTestBean4());
673 		bf.destroySingletons();
674 	}
675 
676 	@Test
677 	public void testConstructorInjectionWithMap() {
678 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
679 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
680 		bpp.setBeanFactory(bf);
681 		bf.addBeanPostProcessor(bpp);
682 		RootBeanDefinition bd = new RootBeanDefinition(MapConstructorInjectionBean.class);
683 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
684 		bf.registerBeanDefinition("annotatedBean", bd);
685 		TestBean tb1 = new TestBean();
686 		TestBean tb2 = new TestBean();
687 		bf.registerSingleton("testBean1", tb1);
688 		bf.registerSingleton("testBean2", tb1);
689 
690 		MapConstructorInjectionBean bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
691 		assertEquals(2, bean.getTestBeanMap().size());
692 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean1"));
693 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean2"));
694 		assertTrue(bean.getTestBeanMap().values().contains(tb1));
695 		assertTrue(bean.getTestBeanMap().values().contains(tb2));
696 
697 		bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
698 		assertEquals(2, bean.getTestBeanMap().size());
699 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean1"));
700 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean2"));
701 		assertTrue(bean.getTestBeanMap().values().contains(tb1));
702 		assertTrue(bean.getTestBeanMap().values().contains(tb2));
703 	}
704 
705 	@Test
706 	public void testFieldInjectionWithMap() {
707 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
708 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
709 		bpp.setBeanFactory(bf);
710 		bf.addBeanPostProcessor(bpp);
711 		RootBeanDefinition bd = new RootBeanDefinition(MapFieldInjectionBean.class);
712 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
713 		bf.registerBeanDefinition("annotatedBean", bd);
714 		TestBean tb1 = new TestBean();
715 		TestBean tb2 = new TestBean();
716 		bf.registerSingleton("testBean1", tb1);
717 		bf.registerSingleton("testBean2", tb1);
718 
719 		MapFieldInjectionBean bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
720 		assertEquals(2, bean.getTestBeanMap().size());
721 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean1"));
722 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean2"));
723 		assertTrue(bean.getTestBeanMap().values().contains(tb1));
724 		assertTrue(bean.getTestBeanMap().values().contains(tb2));
725 
726 		bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
727 		assertEquals(2, bean.getTestBeanMap().size());
728 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean1"));
729 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean2"));
730 		assertTrue(bean.getTestBeanMap().values().contains(tb1));
731 		assertTrue(bean.getTestBeanMap().values().contains(tb2));
732 	}
733 
734 	@Test
735 	public void testMethodInjectionWithMap() {
736 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
737 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
738 		bpp.setBeanFactory(bf);
739 		bf.addBeanPostProcessor(bpp);
740 		RootBeanDefinition bd = new RootBeanDefinition(MapMethodInjectionBean.class);
741 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
742 		bf.registerBeanDefinition("annotatedBean", bd);
743 		TestBean tb = new TestBean();
744 		bf.registerSingleton("testBean", tb);
745 
746 		MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
747 		assertEquals(1, bean.getTestBeanMap().size());
748 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean"));
749 		assertTrue(bean.getTestBeanMap().values().contains(tb));
750 		assertSame(tb, bean.getTestBean());
751 
752 		bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
753 		assertEquals(1, bean.getTestBeanMap().size());
754 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean"));
755 		assertTrue(bean.getTestBeanMap().values().contains(tb));
756 		assertSame(tb, bean.getTestBean());
757 	}
758 
759 	@Test
760 	public void testMethodInjectionWithMapAndMultipleMatches() {
761 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
762 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
763 		bpp.setBeanFactory(bf);
764 		bf.addBeanPostProcessor(bpp);
765 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(MapMethodInjectionBean.class));
766 		bf.registerBeanDefinition("testBean1", new RootBeanDefinition(TestBean.class));
767 		bf.registerBeanDefinition("testBean2", new RootBeanDefinition(TestBean.class));
768 
769 		try {
770 			bf.getBean("annotatedBean");
771 			fail("should have failed, more than one bean of type");
772 		}
773 		catch (BeanCreationException e) {
774 			// expected
775 		}
776 		bf.destroySingletons();
777 	}
778 
779 	@Test
780 	public void testMethodInjectionWithMapAndMultipleMatchesButOnlyOneAutowireCandidate() {
781 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
782 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
783 		bpp.setBeanFactory(bf);
784 		bf.addBeanPostProcessor(bpp);
785 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(MapMethodInjectionBean.class));
786 		bf.registerBeanDefinition("testBean1", new RootBeanDefinition(TestBean.class));
787 		RootBeanDefinition rbd2 = new RootBeanDefinition(TestBean.class);
788 		rbd2.setAutowireCandidate(false);
789 		bf.registerBeanDefinition("testBean2", rbd2);
790 
791 		MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
792 		TestBean tb = (TestBean) bf.getBean("testBean1");
793 		assertEquals(1, bean.getTestBeanMap().size());
794 		assertTrue(bean.getTestBeanMap().keySet().contains("testBean1"));
795 		assertTrue(bean.getTestBeanMap().values().contains(tb));
796 		assertSame(tb, bean.getTestBean());
797 		bf.destroySingletons();
798 	}
799 
800 	@Test
801 	public void testMethodInjectionWithMapAndNoMatches() {
802 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
803 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
804 		bpp.setBeanFactory(bf);
805 		bf.addBeanPostProcessor(bpp);
806 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(MapMethodInjectionBean.class));
807 
808 		MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
809 		assertNull(bean.getTestBeanMap());
810 		assertNull(bean.getTestBean());
811 		bf.destroySingletons();
812 	}
813 
814 	@Test
815 	public void testObjectFactoryInjection() {
816 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
817 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
818 		bpp.setBeanFactory(bf);
819 		bf.addBeanPostProcessor(bpp);
820 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryInjectionBean.class));
821 		bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
822 
823 		ObjectFactoryInjectionBean bean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
824 		assertSame(bf.getBean("testBean"), bean.getTestBean());
825 		bf.destroySingletons();
826 	}
827 
828 	@Test
829 	public void testObjectFactoryInjectionIntoPrototypeBean() {
830 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
831 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
832 		bpp.setBeanFactory(bf);
833 		bf.addBeanPostProcessor(bpp);
834 		RootBeanDefinition annotatedBeanDefinition = new RootBeanDefinition(ObjectFactoryInjectionBean.class);
835 		annotatedBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
836 		bf.registerBeanDefinition("annotatedBean", annotatedBeanDefinition);
837 		bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
838 
839 		ObjectFactoryInjectionBean bean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
840 		assertSame(bf.getBean("testBean"), bean.getTestBean());
841 		ObjectFactoryInjectionBean anotherBean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
842 		assertNotSame(anotherBean, bean);
843 		assertSame(bf.getBean("testBean"), anotherBean.getTestBean());
844 	}
845 
846 	@Test
847 	public void testObjectFactoryQualifierInjection() {
848 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
849 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
850 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
851 		bpp.setBeanFactory(bf);
852 		bf.addBeanPostProcessor(bpp);
853 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryQualifierInjectionBean.class));
854 		RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
855 		bd.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "testBean"));
856 		bf.registerBeanDefinition("testBean", bd);
857 		bf.registerBeanDefinition("testBean2", new RootBeanDefinition(TestBean.class));
858 
859 		ObjectFactoryQualifierInjectionBean bean = (ObjectFactoryQualifierInjectionBean) bf.getBean("annotatedBean");
860 		assertSame(bf.getBean("testBean"), bean.getTestBean());
861 		bf.destroySingletons();
862 	}
863 
864 	@Test
865 	public void testObjectFactorySerialization() throws Exception {
866 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
867 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
868 		bpp.setBeanFactory(bf);
869 		bf.addBeanPostProcessor(bpp);
870 		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryInjectionBean.class));
871 		bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
872 		bf.setSerializationId("test");
873 
874 		ObjectFactoryInjectionBean bean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
875 		assertSame(bf.getBean("testBean"), bean.getTestBean());
876 		bean = (ObjectFactoryInjectionBean) SerializationTestUtils.serializeAndDeserialize(bean);
877 		assertSame(bf.getBean("testBean"), bean.getTestBean());
878 		bf.destroySingletons();
879 	}
880 
881 	@Test
882 	public void testCustomAnnotationRequiredFieldResourceInjection() {
883 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
884 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
885 		bpp.setAutowiredAnnotationType(MyAutowired.class);
886 		bpp.setRequiredParameterName("optional");
887 		bpp.setRequiredParameterValue(false);
888 		bpp.setBeanFactory(bf);
889 		bf.addBeanPostProcessor(bpp);
890 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
891 				CustomAnnotationRequiredFieldResourceInjectionBean.class));
892 		TestBean tb = new TestBean();
893 		bf.registerSingleton("testBean", tb);
894 
895 		CustomAnnotationRequiredFieldResourceInjectionBean bean = (CustomAnnotationRequiredFieldResourceInjectionBean) bf.getBean("customBean");
896 		assertSame(tb, bean.getTestBean());
897 		bf.destroySingletons();
898 	}
899 
900 	@Test
901 	public void testCustomAnnotationRequiredFieldResourceInjectionFailsWhenNoDependencyFound() {
902 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
903 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
904 		bpp.setAutowiredAnnotationType(MyAutowired.class);
905 		bpp.setRequiredParameterName("optional");
906 		bpp.setRequiredParameterValue(false);
907 		bpp.setBeanFactory(bf);
908 		bf.addBeanPostProcessor(bpp);
909 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
910 				CustomAnnotationRequiredFieldResourceInjectionBean.class));
911 
912 		try {
913 			bf.getBean("customBean");
914 			fail("expected BeanCreationException; no dependency available for required field");
915 		}
916 		catch (BeanCreationException e) {
917 			// expected
918 		}
919 		bf.destroySingletons();
920 	}
921 
922 	@Test
923 	public void testCustomAnnotationRequiredFieldResourceInjectionFailsWhenMultipleDependenciesFound() {
924 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
925 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
926 		bpp.setAutowiredAnnotationType(MyAutowired.class);
927 		bpp.setRequiredParameterName("optional");
928 		bpp.setRequiredParameterValue(false);
929 		bpp.setBeanFactory(bf);
930 		bf.addBeanPostProcessor(bpp);
931 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
932 				CustomAnnotationRequiredFieldResourceInjectionBean.class));
933 		TestBean tb1 = new TestBean();
934 		bf.registerSingleton("testBean1", tb1);
935 		TestBean tb2 = new TestBean();
936 		bf.registerSingleton("testBean2", tb2);
937 
938 		try {
939 			bf.getBean("customBean");
940 			fail("expected BeanCreationException; multiple beans of dependency type available");
941 		}
942 		catch (BeanCreationException e) {
943 			// expected
944 		}
945 		bf.destroySingletons();
946 	}
947 
948 	@Test
949 	public void testCustomAnnotationRequiredMethodResourceInjection() {
950 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
951 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
952 		bpp.setAutowiredAnnotationType(MyAutowired.class);
953 		bpp.setRequiredParameterName("optional");
954 		bpp.setRequiredParameterValue(false);
955 		bpp.setBeanFactory(bf);
956 		bf.addBeanPostProcessor(bpp);
957 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
958 				CustomAnnotationRequiredMethodResourceInjectionBean.class));
959 		TestBean tb = new TestBean();
960 		bf.registerSingleton("testBean", tb);
961 
962 		CustomAnnotationRequiredMethodResourceInjectionBean bean = (CustomAnnotationRequiredMethodResourceInjectionBean) bf.getBean("customBean");
963 		assertSame(tb, bean.getTestBean());
964 		bf.destroySingletons();
965 	}
966 
967 	@Test
968 	public void testCustomAnnotationRequiredMethodResourceInjectionFailsWhenNoDependencyFound() {
969 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
970 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
971 		bpp.setAutowiredAnnotationType(MyAutowired.class);
972 		bpp.setRequiredParameterName("optional");
973 		bpp.setRequiredParameterValue(false);
974 		bpp.setBeanFactory(bf);
975 		bf.addBeanPostProcessor(bpp);
976 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
977 				CustomAnnotationRequiredMethodResourceInjectionBean.class));
978 
979 		try {
980 			bf.getBean("customBean");
981 			fail("expected BeanCreationException; no dependency available for required method");
982 		}
983 		catch (BeanCreationException e) {
984 			// expected
985 		}
986 		bf.destroySingletons();
987 	}
988 
989 	@Test
990 	public void testCustomAnnotationRequiredMethodResourceInjectionFailsWhenMultipleDependenciesFound() {
991 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
992 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
993 		bpp.setAutowiredAnnotationType(MyAutowired.class);
994 		bpp.setRequiredParameterName("optional");
995 		bpp.setRequiredParameterValue(false);
996 		bpp.setBeanFactory(bf);
997 		bf.addBeanPostProcessor(bpp);
998 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
999 				CustomAnnotationRequiredMethodResourceInjectionBean.class));
1000 		TestBean tb1 = new TestBean();
1001 		bf.registerSingleton("testBean1", tb1);
1002 		TestBean tb2 = new TestBean();
1003 		bf.registerSingleton("testBean2", tb2);
1004 
1005 		try {
1006 			bf.getBean("customBean");
1007 			fail("expected BeanCreationException; multiple beans of dependency type available");
1008 		}
1009 		catch (BeanCreationException e) {
1010 			// expected
1011 		}
1012 		bf.destroySingletons();
1013 	}
1014 
1015 	@Test
1016 	public void testCustomAnnotationOptionalFieldResourceInjection() {
1017 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1018 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1019 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1020 		bpp.setRequiredParameterName("optional");
1021 		bpp.setRequiredParameterValue(false);
1022 		bpp.setBeanFactory(bf);
1023 		bf.addBeanPostProcessor(bpp);
1024 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1025 				CustomAnnotationOptionalFieldResourceInjectionBean.class));
1026 		TestBean tb = new TestBean();
1027 		bf.registerSingleton("testBean", tb);
1028 
1029 		CustomAnnotationOptionalFieldResourceInjectionBean bean = (CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
1030 		assertSame(tb, bean.getTestBean3());
1031 		assertNull(bean.getTestBean());
1032 		assertNull(bean.getTestBean2());
1033 		bf.destroySingletons();
1034 	}
1035 
1036 	@Test
1037 	public void testCustomAnnotationOptionalFieldResourceInjectionWhenNoDependencyFound() {
1038 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1039 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1040 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1041 		bpp.setRequiredParameterName("optional");
1042 		bpp.setRequiredParameterValue(false);
1043 		bpp.setBeanFactory(bf);
1044 		bf.addBeanPostProcessor(bpp);
1045 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1046 				CustomAnnotationOptionalFieldResourceInjectionBean.class));
1047 
1048 		CustomAnnotationOptionalFieldResourceInjectionBean bean = (CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
1049 		assertNull(bean.getTestBean3());
1050 		assertNull(bean.getTestBean());
1051 		assertNull(bean.getTestBean2());
1052 		bf.destroySingletons();
1053 	}
1054 
1055 	@Test
1056 	public void testCustomAnnotationOptionalFieldResourceInjectionWhenMultipleDependenciesFound() {
1057 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1058 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1059 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1060 		bpp.setRequiredParameterName("optional");
1061 		bpp.setRequiredParameterValue(false);
1062 		bpp.setBeanFactory(bf);
1063 		bf.addBeanPostProcessor(bpp);
1064 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1065 				CustomAnnotationOptionalFieldResourceInjectionBean.class));
1066 		TestBean tb1 = new TestBean();
1067 		bf.registerSingleton("testBean1", tb1);
1068 		TestBean tb2 = new TestBean();
1069 		bf.registerSingleton("testBean2", tb2);
1070 
1071 		try {
1072 			bf.getBean("customBean");
1073 			fail("expected BeanCreationException; multiple beans of dependency type available");
1074 		}
1075 		catch (BeanCreationException e) {
1076 			// expected
1077 		}
1078 		bf.destroySingletons();
1079 	}
1080 
1081 	@Test
1082 	public void testCustomAnnotationOptionalMethodResourceInjection() {
1083 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1084 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1085 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1086 		bpp.setRequiredParameterName("optional");
1087 		bpp.setRequiredParameterValue(false);
1088 		bpp.setBeanFactory(bf);
1089 		bf.addBeanPostProcessor(bpp);
1090 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1091 				CustomAnnotationOptionalMethodResourceInjectionBean.class));
1092 		TestBean tb = new TestBean();
1093 		bf.registerSingleton("testBean", tb);
1094 
1095 		CustomAnnotationOptionalMethodResourceInjectionBean bean = (CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
1096 		assertSame(tb, bean.getTestBean3());
1097 		assertNull(bean.getTestBean());
1098 		assertNull(bean.getTestBean2());
1099 		bf.destroySingletons();
1100 	}
1101 
1102 	@Test
1103 	public void testCustomAnnotationOptionalMethodResourceInjectionWhenNoDependencyFound() {
1104 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1105 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1106 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1107 		bpp.setRequiredParameterName("optional");
1108 		bpp.setRequiredParameterValue(false);
1109 		bpp.setBeanFactory(bf);
1110 		bf.addBeanPostProcessor(bpp);
1111 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1112 				CustomAnnotationOptionalMethodResourceInjectionBean.class));
1113 
1114 		CustomAnnotationOptionalMethodResourceInjectionBean bean = (CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
1115 		assertNull(bean.getTestBean3());
1116 		assertNull(bean.getTestBean());
1117 		assertNull(bean.getTestBean2());
1118 		bf.destroySingletons();
1119 	}
1120 
1121 	@Test
1122 	public void testCustomAnnotationOptionalMethodResourceInjectionWhenMultipleDependenciesFound() {
1123 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1124 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1125 		bpp.setAutowiredAnnotationType(MyAutowired.class);
1126 		bpp.setRequiredParameterName("optional");
1127 		bpp.setRequiredParameterValue(false);
1128 		bpp.setBeanFactory(bf);
1129 		bf.addBeanPostProcessor(bpp);
1130 		bf.registerBeanDefinition("customBean", new RootBeanDefinition(
1131 				CustomAnnotationOptionalMethodResourceInjectionBean.class));
1132 		TestBean tb1 = new TestBean();
1133 		bf.registerSingleton("testBean1", tb1);
1134 		TestBean tb2 = new TestBean();
1135 		bf.registerSingleton("testBean2", tb2);
1136 
1137 		try {
1138 			bf.getBean("customBean");
1139 			fail("expected BeanCreationException; multiple beans of dependency type available");
1140 		}
1141 		catch (BeanCreationException e) {
1142 			// expected
1143 		}
1144 		bf.destroySingletons();
1145 	}
1146 
1147 	/**
1148 	 * Verifies that a dependency on a {@link FactoryBean} can be autowired via
1149 	 * {@link Autowired @Autowired}, specifically addressing the JIRA issue
1150 	 * raised in <a
1151 	 * href="http://opensource.atlassian.com/projects/spring/browse/SPR-4040"
1152 	 * target="_blank">SPR-4040</a>.
1153 	 */
1154 	@Test
1155 	public void testBeanAutowiredWithFactoryBean() {
1156 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1157 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1158 		bpp.setBeanFactory(bf);
1159 		bf.addBeanPostProcessor(bpp);
1160 		bf.registerBeanDefinition("factoryBeanDependentBean", new RootBeanDefinition(FactoryBeanDependentBean.class));
1161 		bf.registerSingleton("stringFactoryBean", new StringFactoryBean());
1162 
1163 		final StringFactoryBean factoryBean = (StringFactoryBean) bf.getBean("&stringFactoryBean");
1164 		final FactoryBeanDependentBean bean = (FactoryBeanDependentBean) bf.getBean("factoryBeanDependentBean");
1165 
1166 		assertNotNull("The singleton StringFactoryBean should have been registered.", factoryBean);
1167 		assertNotNull("The factoryBeanDependentBean should have been registered.", bean);
1168 		assertEquals("The FactoryBeanDependentBean should have been autowired 'by type' with the StringFactoryBean.",
1169 				factoryBean, bean.getFactoryBean());
1170 
1171 		bf.destroySingletons();
1172 	}
1173 
1174 	@Test
1175 	public void testGenericsBasedFieldInjection() {
1176 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1177 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1178 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1179 		bpp.setBeanFactory(bf);
1180 		bf.addBeanPostProcessor(bpp);
1181 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBean.class);
1182 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1183 		bf.registerBeanDefinition("annotatedBean", bd);
1184 		StringRepository sr = new StringRepository();
1185 		bf.registerSingleton("stringRepo", sr);
1186 		IntegerRepository ir = new IntegerRepository();
1187 		bf.registerSingleton("integerRepo", ir);
1188 
1189 		RepositoryFieldInjectionBean bean = (RepositoryFieldInjectionBean) bf.getBean("annotatedBean");
1190 		assertSame(sr, bean.stringRepository);
1191 		assertSame(ir, bean.integerRepository);
1192 		assertSame(1, bean.stringRepositoryArray.length);
1193 		assertSame(1, bean.integerRepositoryArray.length);
1194 		assertSame(sr, bean.stringRepositoryArray[0]);
1195 		assertSame(ir, bean.integerRepositoryArray[0]);
1196 		assertSame(1, bean.stringRepositoryList.size());
1197 		assertSame(1, bean.integerRepositoryList.size());
1198 		assertSame(sr, bean.stringRepositoryList.get(0));
1199 		assertSame(ir, bean.integerRepositoryList.get(0));
1200 		assertSame(1, bean.stringRepositoryMap.size());
1201 		assertSame(1, bean.integerRepositoryMap.size());
1202 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1203 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1204 	}
1205 
1206 	@Test
1207 	public void testGenericsBasedFieldInjectionWithSubstitutedVariables() {
1208 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1209 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1210 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1211 		bpp.setBeanFactory(bf);
1212 		bf.addBeanPostProcessor(bpp);
1213 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSubstitutedVariables.class);
1214 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1215 		bf.registerBeanDefinition("annotatedBean", bd);
1216 		StringRepository sr = new StringRepository();
1217 		bf.registerSingleton("stringRepo", sr);
1218 		IntegerRepository ir = new IntegerRepository();
1219 		bf.registerSingleton("integerRepo", ir);
1220 
1221 		RepositoryFieldInjectionBeanWithSubstitutedVariables bean = (RepositoryFieldInjectionBeanWithSubstitutedVariables) bf.getBean("annotatedBean");
1222 		assertSame(sr, bean.stringRepository);
1223 		assertSame(ir, bean.integerRepository);
1224 		assertSame(1, bean.stringRepositoryArray.length);
1225 		assertSame(1, bean.integerRepositoryArray.length);
1226 		assertSame(sr, bean.stringRepositoryArray[0]);
1227 		assertSame(ir, bean.integerRepositoryArray[0]);
1228 		assertSame(1, bean.stringRepositoryList.size());
1229 		assertSame(1, bean.integerRepositoryList.size());
1230 		assertSame(sr, bean.stringRepositoryList.get(0));
1231 		assertSame(ir, bean.integerRepositoryList.get(0));
1232 		assertSame(1, bean.stringRepositoryMap.size());
1233 		assertSame(1, bean.integerRepositoryMap.size());
1234 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1235 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1236 	}
1237 
1238 	@Test
1239 	public void testGenericsBasedFieldInjectionWithQualifiers() {
1240 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1241 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1242 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1243 		bpp.setBeanFactory(bf);
1244 		bf.addBeanPostProcessor(bpp);
1245 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithQualifiers.class);
1246 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1247 		bf.registerBeanDefinition("annotatedBean", bd);
1248 		StringRepository sr = new StringRepository();
1249 		bf.registerSingleton("stringRepo", sr);
1250 		IntegerRepository ir = new IntegerRepository();
1251 		bf.registerSingleton("integerRepo", ir);
1252 
1253 		RepositoryFieldInjectionBeanWithQualifiers bean = (RepositoryFieldInjectionBeanWithQualifiers) bf.getBean("annotatedBean");
1254 		assertSame(sr, bean.stringRepository);
1255 		assertSame(ir, bean.integerRepository);
1256 		assertSame(1, bean.stringRepositoryArray.length);
1257 		assertSame(1, bean.integerRepositoryArray.length);
1258 		assertSame(sr, bean.stringRepositoryArray[0]);
1259 		assertSame(ir, bean.integerRepositoryArray[0]);
1260 		assertSame(1, bean.stringRepositoryList.size());
1261 		assertSame(1, bean.integerRepositoryList.size());
1262 		assertSame(sr, bean.stringRepositoryList.get(0));
1263 		assertSame(ir, bean.integerRepositoryList.get(0));
1264 		assertSame(1, bean.stringRepositoryMap.size());
1265 		assertSame(1, bean.integerRepositoryMap.size());
1266 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1267 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1268 	}
1269 
1270 	@Test
1271 	public void testGenericsBasedFieldInjectionWithMocks() {
1272 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1273 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1274 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1275 		bpp.setBeanFactory(bf);
1276 		bf.addBeanPostProcessor(bpp);
1277 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithQualifiers.class);
1278 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1279 		bf.registerBeanDefinition("annotatedBean", bd);
1280 
1281 		RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
1282 		bf.registerBeanDefinition("mocksControl", rbd);
1283 		rbd = new RootBeanDefinition();
1284 		rbd.setFactoryBeanName("mocksControl");
1285 		rbd.setFactoryMethodName("createMock");
1286 		rbd.getConstructorArgumentValues().addGenericArgumentValue(Repository.class);
1287 		bf.registerBeanDefinition("stringRepo", rbd);
1288 		rbd = new RootBeanDefinition();
1289 		rbd.setFactoryBeanName("mocksControl");
1290 		rbd.setFactoryMethodName("createMock");
1291 		rbd.getConstructorArgumentValues().addGenericArgumentValue(Repository.class);
1292 		bf.registerBeanDefinition("integerRepo", rbd);
1293 
1294 		RepositoryFieldInjectionBeanWithQualifiers bean = (RepositoryFieldInjectionBeanWithQualifiers) bf.getBean("annotatedBean");
1295 		Repository sr = bf.getBean("stringRepo", Repository.class);
1296 		Repository ir = bf.getBean("integerRepo", Repository.class);
1297 		assertSame(sr, bean.stringRepository);
1298 		assertSame(ir, bean.integerRepository);
1299 		assertSame(1, bean.stringRepositoryArray.length);
1300 		assertSame(1, bean.integerRepositoryArray.length);
1301 		assertSame(sr, bean.stringRepositoryArray[0]);
1302 		assertSame(ir, bean.integerRepositoryArray[0]);
1303 		assertSame(1, bean.stringRepositoryList.size());
1304 		assertSame(1, bean.integerRepositoryList.size());
1305 		assertSame(sr, bean.stringRepositoryList.get(0));
1306 		assertSame(ir, bean.integerRepositoryList.get(0));
1307 		assertSame(1, bean.stringRepositoryMap.size());
1308 		assertSame(1, bean.integerRepositoryMap.size());
1309 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1310 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1311 	}
1312 
1313 	@Test
1314 	public void testGenericsBasedFieldInjectionWithSimpleMatch() {
1315 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1316 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1317 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1318 		bpp.setBeanFactory(bf);
1319 		bf.addBeanPostProcessor(bpp);
1320 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSimpleMatch.class);
1321 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1322 		bf.registerBeanDefinition("annotatedBean", bd);
1323 
1324 		bf.registerSingleton("repo", new StringRepository());
1325 
1326 		RepositoryFieldInjectionBeanWithSimpleMatch bean = (RepositoryFieldInjectionBeanWithSimpleMatch) bf.getBean("annotatedBean");
1327 		Repository repo = bf.getBean("repo", Repository.class);
1328 		assertSame(repo, bean.repository);
1329 		assertSame(repo, bean.stringRepository);
1330 		assertSame(1, bean.repositoryArray.length);
1331 		assertSame(1, bean.stringRepositoryArray.length);
1332 		assertSame(repo, bean.repositoryArray[0]);
1333 		assertSame(repo, bean.stringRepositoryArray[0]);
1334 		assertSame(1, bean.repositoryList.size());
1335 		assertSame(1, bean.stringRepositoryList.size());
1336 		assertSame(repo, bean.repositoryList.get(0));
1337 		assertSame(repo, bean.stringRepositoryList.get(0));
1338 		assertSame(1, bean.repositoryMap.size());
1339 		assertSame(1, bean.stringRepositoryMap.size());
1340 		assertSame(repo, bean.repositoryMap.get("repo"));
1341 		assertSame(repo, bean.stringRepositoryMap.get("repo"));
1342 	}
1343 
1344 	@Test
1345 	public void testGenericsBasedFactoryBeanInjectionWithBeanDefinition() {
1346 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1347 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1348 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1349 		bpp.setBeanFactory(bf);
1350 		bf.addBeanPostProcessor(bpp);
1351 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
1352 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1353 		bf.registerBeanDefinition("annotatedBean", bd);
1354 		bf.registerBeanDefinition("repoFactoryBean", new RootBeanDefinition(RepositoryFactoryBean.class));
1355 
1356 		RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean");
1357 		RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class);
1358 		assertSame(repoFactoryBean, bean.repositoryFactoryBean);
1359 	}
1360 
1361 	@Test
1362 	public void testGenericsBasedFactoryBeanInjectionWithSingletonBean() {
1363 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1364 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1365 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1366 		bpp.setBeanFactory(bf);
1367 		bf.addBeanPostProcessor(bpp);
1368 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
1369 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1370 		bf.registerBeanDefinition("annotatedBean", bd);
1371 		bf.registerSingleton("repoFactoryBean", new RepositoryFactoryBean<>());
1372 
1373 		RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean");
1374 		RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class);
1375 		assertSame(repoFactoryBean, bean.repositoryFactoryBean);
1376 	}
1377 
1378 	@Test
1379 	public void testGenericsBasedFieldInjectionWithSimpleMatchAndMock() {
1380 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1381 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1382 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1383 		bpp.setBeanFactory(bf);
1384 		bf.addBeanPostProcessor(bpp);
1385 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSimpleMatch.class);
1386 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1387 		bf.registerBeanDefinition("annotatedBean", bd);
1388 
1389 		RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
1390 		bf.registerBeanDefinition("mocksControl", rbd);
1391 		rbd = new RootBeanDefinition();
1392 		rbd.setFactoryBeanName("mocksControl");
1393 		rbd.setFactoryMethodName("createMock");
1394 		rbd.getConstructorArgumentValues().addGenericArgumentValue(Repository.class);
1395 		bf.registerBeanDefinition("repo", rbd);
1396 
1397 		RepositoryFieldInjectionBeanWithSimpleMatch bean = (RepositoryFieldInjectionBeanWithSimpleMatch) bf.getBean("annotatedBean");
1398 		Repository repo = bf.getBean("repo", Repository.class);
1399 		assertSame(repo, bean.repository);
1400 		assertSame(repo, bean.stringRepository);
1401 		assertSame(1, bean.repositoryArray.length);
1402 		assertSame(1, bean.stringRepositoryArray.length);
1403 		assertSame(repo, bean.repositoryArray[0]);
1404 		assertSame(repo, bean.stringRepositoryArray[0]);
1405 		assertSame(1, bean.repositoryList.size());
1406 		assertSame(1, bean.stringRepositoryList.size());
1407 		assertSame(repo, bean.repositoryList.get(0));
1408 		assertSame(repo, bean.stringRepositoryList.get(0));
1409 		assertSame(1, bean.repositoryMap.size());
1410 		assertSame(1, bean.stringRepositoryMap.size());
1411 		assertSame(repo, bean.repositoryMap.get("repo"));
1412 		assertSame(repo, bean.stringRepositoryMap.get("repo"));
1413 	}
1414 
1415 	@Test
1416 	public void testGenericsBasedFieldInjectionWithSimpleMatchAndMockito() {
1417 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1418 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1419 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1420 		bpp.setBeanFactory(bf);
1421 		bf.addBeanPostProcessor(bpp);
1422 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSimpleMatch.class);
1423 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1424 		bf.registerBeanDefinition("annotatedBean", bd);
1425 
1426 		RootBeanDefinition rbd = new RootBeanDefinition();
1427 		rbd.setBeanClassName(Mockito.class.getName());
1428 		rbd.setFactoryMethodName("mock");
1429 		// TypedStringValue used to be equivalent to an XML-defined argument String
1430 		rbd.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue(Repository.class.getName()));
1431 		bf.registerBeanDefinition("repo", rbd);
1432 
1433 		RepositoryFieldInjectionBeanWithSimpleMatch bean = (RepositoryFieldInjectionBeanWithSimpleMatch) bf.getBean("annotatedBean");
1434 		Repository repo = bf.getBean("repo", Repository.class);
1435 		assertSame(repo, bean.repository);
1436 		assertSame(repo, bean.stringRepository);
1437 		assertSame(1, bean.repositoryArray.length);
1438 		assertSame(1, bean.stringRepositoryArray.length);
1439 		assertSame(repo, bean.repositoryArray[0]);
1440 		assertSame(repo, bean.stringRepositoryArray[0]);
1441 		assertSame(1, bean.repositoryList.size());
1442 		assertSame(1, bean.stringRepositoryList.size());
1443 		assertSame(repo, bean.repositoryList.get(0));
1444 		assertSame(repo, bean.stringRepositoryList.get(0));
1445 		assertSame(1, bean.repositoryMap.size());
1446 		assertSame(1, bean.stringRepositoryMap.size());
1447 		assertSame(repo, bean.repositoryMap.get("repo"));
1448 		assertSame(repo, bean.stringRepositoryMap.get("repo"));
1449 	}
1450 
1451 	@Test
1452 	public void testGenericsBasedMethodInjection() {
1453 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1454 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1455 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1456 		bpp.setBeanFactory(bf);
1457 		bf.addBeanPostProcessor(bpp);
1458 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryMethodInjectionBean.class);
1459 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1460 		bf.registerBeanDefinition("annotatedBean", bd);
1461 		StringRepository sr = new StringRepository();
1462 		bf.registerSingleton("stringRepo", sr);
1463 		IntegerRepository ir = new IntegerRepository();
1464 		bf.registerSingleton("integerRepo", ir);
1465 
1466 		RepositoryMethodInjectionBean bean = (RepositoryMethodInjectionBean) bf.getBean("annotatedBean");
1467 		assertSame(sr, bean.stringRepository);
1468 		assertSame(ir, bean.integerRepository);
1469 		assertSame(1, bean.stringRepositoryArray.length);
1470 		assertSame(1, bean.integerRepositoryArray.length);
1471 		assertSame(sr, bean.stringRepositoryArray[0]);
1472 		assertSame(ir, bean.integerRepositoryArray[0]);
1473 		assertSame(1, bean.stringRepositoryList.size());
1474 		assertSame(1, bean.integerRepositoryList.size());
1475 		assertSame(sr, bean.stringRepositoryList.get(0));
1476 		assertSame(ir, bean.integerRepositoryList.get(0));
1477 		assertSame(1, bean.stringRepositoryMap.size());
1478 		assertSame(1, bean.integerRepositoryMap.size());
1479 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1480 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1481 	}
1482 
1483 	@Test
1484 	public void testGenericsBasedMethodInjectionWithSubstitutedVariables() {
1485 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1486 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1487 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1488 		bpp.setBeanFactory(bf);
1489 		bf.addBeanPostProcessor(bpp);
1490 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryMethodInjectionBeanWithSubstitutedVariables.class);
1491 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1492 		bf.registerBeanDefinition("annotatedBean", bd);
1493 		StringRepository sr = new StringRepository();
1494 		bf.registerSingleton("stringRepo", sr);
1495 		IntegerRepository ir = new IntegerRepository();
1496 		bf.registerSingleton("integerRepo", ir);
1497 
1498 		RepositoryMethodInjectionBeanWithSubstitutedVariables bean = (RepositoryMethodInjectionBeanWithSubstitutedVariables) bf.getBean("annotatedBean");
1499 		assertSame(sr, bean.stringRepository);
1500 		assertSame(ir, bean.integerRepository);
1501 		assertSame(1, bean.stringRepositoryArray.length);
1502 		assertSame(1, bean.integerRepositoryArray.length);
1503 		assertSame(sr, bean.stringRepositoryArray[0]);
1504 		assertSame(ir, bean.integerRepositoryArray[0]);
1505 		assertSame(1, bean.stringRepositoryList.size());
1506 		assertSame(1, bean.integerRepositoryList.size());
1507 		assertSame(sr, bean.stringRepositoryList.get(0));
1508 		assertSame(ir, bean.integerRepositoryList.get(0));
1509 		assertSame(1, bean.stringRepositoryMap.size());
1510 		assertSame(1, bean.integerRepositoryMap.size());
1511 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1512 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1513 	}
1514 
1515 	@Test
1516 	public void testGenericsBasedConstructorInjection() {
1517 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1518 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1519 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1520 		bpp.setBeanFactory(bf);
1521 		bf.addBeanPostProcessor(bpp);
1522 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
1523 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1524 		bf.registerBeanDefinition("annotatedBean", bd);
1525 		StringRepository sr = new StringRepository();
1526 		bf.registerSingleton("stringRepo", sr);
1527 		IntegerRepository ir = new IntegerRepository();
1528 		bf.registerSingleton("integerRepo", ir);
1529 
1530 		RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
1531 		assertSame(sr, bean.stringRepository);
1532 		assertSame(ir, bean.integerRepository);
1533 		assertSame(1, bean.stringRepositoryArray.length);
1534 		assertSame(1, bean.integerRepositoryArray.length);
1535 		assertSame(sr, bean.stringRepositoryArray[0]);
1536 		assertSame(ir, bean.integerRepositoryArray[0]);
1537 		assertSame(1, bean.stringRepositoryList.size());
1538 		assertSame(1, bean.integerRepositoryList.size());
1539 		assertSame(sr, bean.stringRepositoryList.get(0));
1540 		assertSame(ir, bean.integerRepositoryList.get(0));
1541 		assertSame(1, bean.stringRepositoryMap.size());
1542 		assertSame(1, bean.integerRepositoryMap.size());
1543 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1544 		assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
1545 	}
1546 
1547 	@Test
1548 	public void testGenericsBasedConstructorInjectionWithNonTypedTarget() {
1549 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1550 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1551 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1552 		bpp.setBeanFactory(bf);
1553 		bf.addBeanPostProcessor(bpp);
1554 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
1555 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1556 		bf.registerBeanDefinition("annotatedBean", bd);
1557 		GenericRepository gr = new GenericRepository();
1558 		bf.registerSingleton("genericRepo", gr);
1559 
1560 		RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
1561 		assertSame(gr, bean.stringRepository);
1562 		assertSame(gr, bean.integerRepository);
1563 		assertSame(1, bean.stringRepositoryArray.length);
1564 		assertSame(1, bean.integerRepositoryArray.length);
1565 		assertSame(gr, bean.stringRepositoryArray[0]);
1566 		assertSame(gr, bean.integerRepositoryArray[0]);
1567 		assertSame(1, bean.stringRepositoryList.size());
1568 		assertSame(1, bean.integerRepositoryList.size());
1569 		assertSame(gr, bean.stringRepositoryList.get(0));
1570 		assertSame(gr, bean.integerRepositoryList.get(0));
1571 		assertSame(1, bean.stringRepositoryMap.size());
1572 		assertSame(1, bean.integerRepositoryMap.size());
1573 		assertSame(gr, bean.stringRepositoryMap.get("genericRepo"));
1574 		assertSame(gr, bean.integerRepositoryMap.get("genericRepo"));
1575 	}
1576 
1577 	@Test
1578 	public void testGenericsBasedConstructorInjectionWithNonGenericTarget() {
1579 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1580 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1581 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1582 		bpp.setBeanFactory(bf);
1583 		bf.addBeanPostProcessor(bpp);
1584 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
1585 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1586 		bf.registerBeanDefinition("annotatedBean", bd);
1587 		SimpleRepository ngr = new SimpleRepository();
1588 		bf.registerSingleton("simpleRepo", ngr);
1589 
1590 		RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
1591 		assertSame(ngr, bean.stringRepository);
1592 		assertSame(ngr, bean.integerRepository);
1593 		assertSame(1, bean.stringRepositoryArray.length);
1594 		assertSame(1, bean.integerRepositoryArray.length);
1595 		assertSame(ngr, bean.stringRepositoryArray[0]);
1596 		assertSame(ngr, bean.integerRepositoryArray[0]);
1597 		assertSame(1, bean.stringRepositoryList.size());
1598 		assertSame(1, bean.integerRepositoryList.size());
1599 		assertSame(ngr, bean.stringRepositoryList.get(0));
1600 		assertSame(ngr, bean.integerRepositoryList.get(0));
1601 		assertSame(1, bean.stringRepositoryMap.size());
1602 		assertSame(1, bean.integerRepositoryMap.size());
1603 		assertSame(ngr, bean.stringRepositoryMap.get("simpleRepo"));
1604 		assertSame(ngr, bean.integerRepositoryMap.get("simpleRepo"));
1605 	}
1606 
1607 	@Test
1608 	public void testGenericsBasedConstructorInjectionWithMixedTargets() {
1609 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1610 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1611 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1612 		bpp.setBeanFactory(bf);
1613 		bf.addBeanPostProcessor(bpp);
1614 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
1615 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1616 		bf.registerBeanDefinition("annotatedBean", bd);
1617 		StringRepository sr = new StringRepository();
1618 		bf.registerSingleton("stringRepo", sr);
1619 		GenericRepository gr = new GenericRepositorySubclass();
1620 		bf.registerSingleton("genericRepo", gr);
1621 
1622 		RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
1623 		assertSame(sr, bean.stringRepository);
1624 		assertSame(gr, bean.integerRepository);
1625 		assertSame(1, bean.stringRepositoryArray.length);
1626 		assertSame(1, bean.integerRepositoryArray.length);
1627 		assertSame(sr, bean.stringRepositoryArray[0]);
1628 		assertSame(gr, bean.integerRepositoryArray[0]);
1629 		assertSame(1, bean.stringRepositoryList.size());
1630 		assertSame(1, bean.integerRepositoryList.size());
1631 		assertSame(sr, bean.stringRepositoryList.get(0));
1632 		assertSame(gr, bean.integerRepositoryList.get(0));
1633 		assertSame(1, bean.stringRepositoryMap.size());
1634 		assertSame(1, bean.integerRepositoryMap.size());
1635 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1636 		assertSame(gr, bean.integerRepositoryMap.get("genericRepo"));
1637 	}
1638 
1639 	@Test
1640 	public void testGenericsBasedConstructorInjectionWithMixedTargetsIncludingNonGeneric() {
1641 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1642 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1643 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1644 		bpp.setBeanFactory(bf);
1645 		bf.addBeanPostProcessor(bpp);
1646 		RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
1647 		bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1648 		bf.registerBeanDefinition("annotatedBean", bd);
1649 		StringRepository sr = new StringRepository();
1650 		bf.registerSingleton("stringRepo", sr);
1651 		SimpleRepository ngr = new SimpleRepositorySubclass();
1652 		bf.registerSingleton("simpleRepo", ngr);
1653 
1654 		RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
1655 		assertSame(sr, bean.stringRepository);
1656 		assertSame(ngr, bean.integerRepository);
1657 		assertSame(1, bean.stringRepositoryArray.length);
1658 		assertSame(1, bean.integerRepositoryArray.length);
1659 		assertSame(sr, bean.stringRepositoryArray[0]);
1660 		assertSame(ngr, bean.integerRepositoryArray[0]);
1661 		assertSame(1, bean.stringRepositoryList.size());
1662 		assertSame(1, bean.integerRepositoryList.size());
1663 		assertSame(sr, bean.stringRepositoryList.get(0));
1664 		assertSame(ngr, bean.integerRepositoryList.get(0));
1665 		assertSame(1, bean.stringRepositoryMap.size());
1666 		assertSame(1, bean.integerRepositoryMap.size());
1667 		assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
1668 		assertSame(ngr, bean.integerRepositoryMap.get("simpleRepo"));
1669 	}
1670 
1671 	@Test
1672 	public void testGenericsBasedInjectionIntoMatchingTypeVariable() {
1673 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1674 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1675 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1676 		bpp.setBeanFactory(bf);
1677 		bf.addBeanPostProcessor(bpp);
1678 		RootBeanDefinition bd = new RootBeanDefinition(GenericInterface1Impl.class);
1679 		bd.setFactoryMethodName("create");
1680 		bf.registerBeanDefinition("bean1", bd);
1681 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(GenericInterface2Impl.class));
1682 
1683 		GenericInterface1Impl bean1 = (GenericInterface1Impl) bf.getBean("bean1");
1684 		GenericInterface2Impl bean2 = (GenericInterface2Impl) bf.getBean("bean2");
1685 		assertSame(bean2, bean1.gi2);
1686 	}
1687 
1688 	@Test
1689 	public void testGenericsBasedInjectionIntoUnresolvedTypeVariable() {
1690 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1691 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1692 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1693 		bpp.setBeanFactory(bf);
1694 		bf.addBeanPostProcessor(bpp);
1695 		RootBeanDefinition bd = new RootBeanDefinition(GenericInterface1Impl.class);
1696 		bd.setFactoryMethodName("createPlain");
1697 		bf.registerBeanDefinition("bean1", bd);
1698 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(GenericInterface2Impl.class));
1699 
1700 		GenericInterface1Impl bean1 = (GenericInterface1Impl) bf.getBean("bean1");
1701 		GenericInterface2Impl bean2 = (GenericInterface2Impl) bf.getBean("bean2");
1702 		assertSame(bean2, bean1.gi2);
1703 	}
1704 
1705 	@Test
1706 	public void testGenericsBasedInjectionIntoTypeVariableSelectingBestMatch() {
1707 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1708 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1709 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1710 		bpp.setBeanFactory(bf);
1711 		bf.addBeanPostProcessor(bpp);
1712 		RootBeanDefinition bd = new RootBeanDefinition(GenericInterface1Impl.class);
1713 		bd.setFactoryMethodName("create");
1714 		bf.registerBeanDefinition("bean1", bd);
1715 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(GenericInterface2Impl.class));
1716 		bf.registerBeanDefinition("bean2a", new RootBeanDefinition(ReallyGenericInterface2Impl.class));
1717 		bf.registerBeanDefinition("bean2b", new RootBeanDefinition(PlainGenericInterface2Impl.class));
1718 
1719 		GenericInterface1Impl bean1 = (GenericInterface1Impl) bf.getBean("bean1");
1720 		GenericInterface2Impl bean2 = (GenericInterface2Impl) bf.getBean("bean2");
1721 		assertSame(bean2, bean1.gi2);
1722 	}
1723 
1724 	@Test
1725 	@Ignore  // SPR-11521
1726 	public void testGenericsBasedInjectionIntoTypeVariableSelectingBestMatchAgainstFactoryMethodSignature() {
1727 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1728 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1729 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1730 		bpp.setBeanFactory(bf);
1731 		bf.addBeanPostProcessor(bpp);
1732 		RootBeanDefinition bd = new RootBeanDefinition(GenericInterface1Impl.class);
1733 		bd.setFactoryMethodName("createErased");
1734 		bf.registerBeanDefinition("bean1", bd);
1735 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(GenericInterface2Impl.class));
1736 		bf.registerBeanDefinition("bean2a", new RootBeanDefinition(ReallyGenericInterface2Impl.class));
1737 		bf.registerBeanDefinition("bean2b", new RootBeanDefinition(PlainGenericInterface2Impl.class));
1738 
1739 		GenericInterface1Impl bean1 = (GenericInterface1Impl) bf.getBean("bean1");
1740 		GenericInterface2Impl bean2 = (GenericInterface2Impl) bf.getBean("bean2");
1741 		assertSame(bean2, bean1.gi2);
1742 	}
1743 
1744 	@Test
1745 	public void testCircularTypeReference() {
1746 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1747 		bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1748 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1749 		bpp.setBeanFactory(bf);
1750 		bf.addBeanPostProcessor(bpp);
1751 		bf.registerBeanDefinition("bean1", new RootBeanDefinition(StockServiceImpl.class));
1752 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(StockMovementDaoImpl.class));
1753 		bf.registerBeanDefinition("bean3", new RootBeanDefinition(StockMovementImpl.class));
1754 		bf.registerBeanDefinition("bean4", new RootBeanDefinition(StockMovementInstructionImpl.class));
1755 
1756 		StockServiceImpl service = bf.getBean(StockServiceImpl.class);
1757 		assertSame(bf.getBean(StockMovementDaoImpl.class), service.stockMovementDao);
1758 	}
1759 
1760 	@Test
1761 	public void testBridgeMethodHandling() {
1762 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1763 		AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1764 		bpp.setBeanFactory(bf);
1765 		bf.addBeanPostProcessor(bpp);
1766 		bf.registerBeanDefinition("bean1", new RootBeanDefinition(MyCallable.class));
1767 		bf.registerBeanDefinition("bean2", new RootBeanDefinition(SecondCallable.class));
1768 		bf.registerBeanDefinition("bean3", new RootBeanDefinition(FooBar.class));
1769 		assertNotNull(bf.getBean(FooBar.class));
1770 	}
1771 
1772 
1773 	public static class ResourceInjectionBean {
1774 
1775 		@Autowired(required = false)
1776 		private TestBean testBean;
1777 
1778 		private TestBean testBean2;
1779 
1780 		@Autowired
1781 		public void setTestBean2(TestBean testBean2) {
1782 			if (this.testBean2 != null) {
1783 				throw new IllegalStateException("Already called");
1784 			}
1785 			this.testBean2 = testBean2;
1786 		}
1787 
1788 		public TestBean getTestBean() {
1789 			return this.testBean;
1790 		}
1791 
1792 		public TestBean getTestBean2() {
1793 			return this.testBean2;
1794 		}
1795 	}
1796 
1797 
1798 	static class NonPublicResourceInjectionBean<T> extends ResourceInjectionBean {
1799 
1800 		@Autowired
1801 		public final ITestBean testBean3 = null;
1802 
1803 		private T nestedTestBean;
1804 
1805 		private ITestBean testBean4;
1806 
1807 		protected BeanFactory beanFactory;
1808 
1809 		public boolean baseInjected = false;
1810 
1811 		public NonPublicResourceInjectionBean() {
1812 		}
1813 
1814 		@Override
1815 		@Autowired @Required
1816 		public void setTestBean2(TestBean testBean2) {
1817 			super.setTestBean2(testBean2);
1818 		}
1819 
1820 		@Autowired
1821 		private void inject(ITestBean testBean4, T nestedTestBean) {
1822 			this.testBean4 = testBean4;
1823 			this.nestedTestBean = nestedTestBean;
1824 		}
1825 
1826 		@Autowired
1827 		private void inject(ITestBean testBean4) {
1828 			this.baseInjected = true;
1829 		}
1830 
1831 		@Autowired
1832 		protected void initBeanFactory(BeanFactory beanFactory) {
1833 			this.beanFactory = beanFactory;
1834 		}
1835 
1836 		public ITestBean getTestBean3() {
1837 			return this.testBean3;
1838 		}
1839 
1840 		public ITestBean getTestBean4() {
1841 			return this.testBean4;
1842 		}
1843 
1844 		public T getNestedTestBean() {
1845 			return this.nestedTestBean;
1846 		}
1847 
1848 		public BeanFactory getBeanFactory() {
1849 			return this.beanFactory;
1850 		}
1851 	}
1852 
1853 
1854 	public static class TypedExtendedResourceInjectionBean extends NonPublicResourceInjectionBean<NestedTestBean> {
1855 	}
1856 
1857 
1858 	public static class OverriddenExtendedResourceInjectionBean extends NonPublicResourceInjectionBean<NestedTestBean> {
1859 
1860 		public boolean subInjected = false;
1861 
1862 		@Override
1863 		public void setTestBean2(TestBean testBean2) {
1864 			super.setTestBean2(testBean2);
1865 		}
1866 
1867 		@Override
1868 		protected void initBeanFactory(BeanFactory beanFactory) {
1869 			this.beanFactory = beanFactory;
1870 		}
1871 
1872 		@Autowired
1873 		private void inject(ITestBean testBean4) {
1874 			this.subInjected = true;
1875 		}
1876 	}
1877 
1878 
1879 	public static class OptionalResourceInjectionBean extends ResourceInjectionBean {
1880 
1881 		@Autowired(required = false)
1882 		protected ITestBean testBean3;
1883 
1884 		private IndexedTestBean indexedTestBean;
1885 
1886 		private NestedTestBean[] nestedTestBeans;
1887 
1888 		@Autowired(required = false)
1889 		public NestedTestBean[] nestedTestBeansField;
1890 
1891 		private ITestBean testBean4;
1892 
1893 		@Override
1894 		@Autowired(required = false)
1895 		public void setTestBean2(TestBean testBean2) {
1896 			super.setTestBean2(testBean2);
1897 		}
1898 
1899 		@Autowired(required = false)
1900 		private void inject(ITestBean testBean4, NestedTestBean[] nestedTestBeans, IndexedTestBean indexedTestBean) {
1901 			this.testBean4 = testBean4;
1902 			this.indexedTestBean = indexedTestBean;
1903 			this.nestedTestBeans = nestedTestBeans;
1904 		}
1905 
1906 		public ITestBean getTestBean3() {
1907 			return this.testBean3;
1908 		}
1909 
1910 		public ITestBean getTestBean4() {
1911 			return this.testBean4;
1912 		}
1913 
1914 		public IndexedTestBean getIndexedTestBean() {
1915 			return this.indexedTestBean;
1916 		}
1917 
1918 		public NestedTestBean[] getNestedTestBeans() {
1919 			return this.nestedTestBeans;
1920 		}
1921 	}
1922 
1923 
1924 	public static class OptionalCollectionResourceInjectionBean extends ResourceInjectionBean {
1925 
1926 		@Autowired(required = false)
1927 		protected ITestBean testBean3;
1928 
1929 		private IndexedTestBean indexedTestBean;
1930 
1931 		private List<NestedTestBean> nestedTestBeans;
1932 
1933 		public List<NestedTestBean> nestedTestBeansSetter;
1934 
1935 		@Autowired(required = false)
1936 		public List<NestedTestBean> nestedTestBeansField;
1937 
1938 		private ITestBean testBean4;
1939 
1940 		@Override
1941 		@Autowired(required = false)
1942 		public void setTestBean2(TestBean testBean2) {
1943 			super.setTestBean2(testBean2);
1944 		}
1945 
1946 		@Autowired(required = false)
1947 		private void inject(ITestBean testBean4, List<NestedTestBean> nestedTestBeans, IndexedTestBean indexedTestBean) {
1948 			this.testBean4 = testBean4;
1949 			this.indexedTestBean = indexedTestBean;
1950 			this.nestedTestBeans = nestedTestBeans;
1951 		}
1952 
1953 		@Autowired(required = false)
1954 		public void setNestedTestBeans(List<NestedTestBean> nestedTestBeans) {
1955 			this.nestedTestBeansSetter = nestedTestBeans;
1956 		}
1957 
1958 		public ITestBean getTestBean3() {
1959 			return this.testBean3;
1960 		}
1961 
1962 		public ITestBean getTestBean4() {
1963 			return this.testBean4;
1964 		}
1965 
1966 		public IndexedTestBean getIndexedTestBean() {
1967 			return this.indexedTestBean;
1968 		}
1969 
1970 		public List<NestedTestBean> getNestedTestBeans() {
1971 			return this.nestedTestBeans;
1972 		}
1973 	}
1974 
1975 
1976 	public static class ConstructorResourceInjectionBean extends ResourceInjectionBean {
1977 
1978 		@Autowired
1979 		protected ITestBean testBean3;
1980 
1981 		private ITestBean testBean4;
1982 
1983 		private NestedTestBean nestedTestBean;
1984 
1985 		private ConfigurableListableBeanFactory beanFactory;
1986 
1987 
1988 		public ConstructorResourceInjectionBean() {
1989 			throw new UnsupportedOperationException();
1990 		}
1991 
1992 		public ConstructorResourceInjectionBean(ITestBean testBean3) {
1993 			throw new UnsupportedOperationException();
1994 		}
1995 
1996 		@Autowired
1997 		public ConstructorResourceInjectionBean(ITestBean testBean4, NestedTestBean nestedTestBean,
1998 				ConfigurableListableBeanFactory beanFactory) {
1999 			this.testBean4 = testBean4;
2000 			this.nestedTestBean = nestedTestBean;
2001 			this.beanFactory = beanFactory;
2002 		}
2003 
2004 		public ConstructorResourceInjectionBean(NestedTestBean nestedTestBean) {
2005 			throw new UnsupportedOperationException();
2006 		}
2007 
2008 		public ConstructorResourceInjectionBean(ITestBean testBean3, ITestBean testBean4, NestedTestBean nestedTestBean) {
2009 			throw new UnsupportedOperationException();
2010 		}
2011 
2012 		@Override
2013 		@Autowired
2014 		public void setTestBean2(TestBean testBean2) {
2015 			super.setTestBean2(testBean2);
2016 		}
2017 
2018 		public ITestBean getTestBean3() {
2019 			return this.testBean3;
2020 		}
2021 
2022 		public ITestBean getTestBean4() {
2023 			return this.testBean4;
2024 		}
2025 
2026 		public NestedTestBean getNestedTestBean() {
2027 			return this.nestedTestBean;
2028 		}
2029 
2030 		public ConfigurableListableBeanFactory getBeanFactory() {
2031 			return this.beanFactory;
2032 		}
2033 	}
2034 
2035 
2036 	public static class ConstructorsResourceInjectionBean {
2037 
2038 		protected ITestBean testBean3;
2039 
2040 		private ITestBean testBean4;
2041 
2042 		private NestedTestBean[] nestedTestBeans;
2043 
2044 		public ConstructorsResourceInjectionBean() {
2045 		}
2046 
2047 		@Autowired(required = false)
2048 		public ConstructorsResourceInjectionBean(ITestBean testBean3) {
2049 			this.testBean3 = testBean3;
2050 		}
2051 
2052 		@Autowired(required = false)
2053 		public ConstructorsResourceInjectionBean(ITestBean testBean4, NestedTestBean[] nestedTestBeans) {
2054 			this.testBean4 = testBean4;
2055 			this.nestedTestBeans = nestedTestBeans;
2056 		}
2057 
2058 		public ConstructorsResourceInjectionBean(NestedTestBean nestedTestBean) {
2059 			throw new UnsupportedOperationException();
2060 		}
2061 
2062 		public ConstructorsResourceInjectionBean(ITestBean testBean3, ITestBean testBean4, NestedTestBean nestedTestBean) {
2063 			throw new UnsupportedOperationException();
2064 		}
2065 
2066 		public ITestBean getTestBean3() {
2067 			return this.testBean3;
2068 		}
2069 
2070 		public ITestBean getTestBean4() {
2071 			return this.testBean4;
2072 		}
2073 
2074 		public NestedTestBean[] getNestedTestBeans() {
2075 			return this.nestedTestBeans;
2076 		}
2077 	}
2078 
2079 
2080 	public static class ConstructorWithoutFallbackBean {
2081 
2082 		protected ITestBean testBean3;
2083 
2084 		@Autowired(required = false)
2085 		public ConstructorWithoutFallbackBean(ITestBean testBean3) {
2086 			this.testBean3 = testBean3;
2087 		}
2088 
2089 		public ITestBean getTestBean3() {
2090 			return this.testBean3;
2091 		}
2092 	}
2093 
2094 
2095 	public static class ConstructorsCollectionResourceInjectionBean {
2096 
2097 		protected ITestBean testBean3;
2098 
2099 		private ITestBean testBean4;
2100 
2101 		private List<NestedTestBean> nestedTestBeans;
2102 
2103 		public ConstructorsCollectionResourceInjectionBean() {
2104 		}
2105 
2106 		@Autowired(required = false)
2107 		public ConstructorsCollectionResourceInjectionBean(ITestBean testBean3) {
2108 			this.testBean3 = testBean3;
2109 		}
2110 
2111 		@Autowired(required = false)
2112 		public ConstructorsCollectionResourceInjectionBean(ITestBean testBean4, List<NestedTestBean> nestedTestBeans) {
2113 			this.testBean4 = testBean4;
2114 			this.nestedTestBeans = nestedTestBeans;
2115 		}
2116 
2117 		public ConstructorsCollectionResourceInjectionBean(NestedTestBean nestedTestBean) {
2118 			throw new UnsupportedOperationException();
2119 		}
2120 
2121 		public ConstructorsCollectionResourceInjectionBean(ITestBean testBean3, ITestBean testBean4,
2122 				NestedTestBean nestedTestBean) {
2123 			throw new UnsupportedOperationException();
2124 		}
2125 
2126 		public ITestBean getTestBean3() {
2127 			return this.testBean3;
2128 		}
2129 
2130 		public ITestBean getTestBean4() {
2131 			return this.testBean4;
2132 		}
2133 
2134 		public List<NestedTestBean> getNestedTestBeans() {
2135 			return this.nestedTestBeans;
2136 		}
2137 	}
2138 
2139 
2140 	public static class MapConstructorInjectionBean {
2141 
2142 		private Map<String, TestBean> testBeanMap;
2143 
2144 		@Autowired
2145 		public MapConstructorInjectionBean(Map<String, TestBean> testBeanMap) {
2146 			this.testBeanMap = testBeanMap;
2147 		}
2148 
2149 		public Map<String, TestBean> getTestBeanMap() {
2150 			return this.testBeanMap;
2151 		}
2152 	}
2153 
2154 
2155 	public static class MapFieldInjectionBean {
2156 
2157 		@Autowired
2158 		private Map<String, TestBean> testBeanMap;
2159 
2160 		public Map<String, TestBean> getTestBeanMap() {
2161 			return this.testBeanMap;
2162 		}
2163 	}
2164 
2165 
2166 	public static class MapMethodInjectionBean {
2167 
2168 		private TestBean testBean;
2169 
2170 		private Map<String, TestBean> testBeanMap;
2171 
2172 		@Autowired(required = false)
2173 		public void setTestBeanMap(TestBean testBean, Map<String, TestBean> testBeanMap) {
2174 			this.testBean = testBean;
2175 			this.testBeanMap = testBeanMap;
2176 		}
2177 
2178 		public TestBean getTestBean() {
2179 			return this.testBean;
2180 		}
2181 
2182 		public Map<String, TestBean> getTestBeanMap() {
2183 			return this.testBeanMap;
2184 		}
2185 	}
2186 
2187 
2188 	@SuppressWarnings("serial")
2189 	public static class ObjectFactoryInjectionBean implements Serializable {
2190 
2191 		@Autowired
2192 		private ObjectFactory<TestBean> testBeanFactory;
2193 
2194 		public TestBean getTestBean() {
2195 			return this.testBeanFactory.getObject();
2196 		}
2197 	}
2198 
2199 
2200 	public static class ObjectFactoryQualifierInjectionBean {
2201 
2202 		@Autowired
2203 		@Qualifier("testBean")
2204 		private ObjectFactory<?> testBeanFactory;
2205 
2206 		public TestBean getTestBean() {
2207 			return (TestBean) this.testBeanFactory.getObject();
2208 		}
2209 	}
2210 
2211 
2212 	public static class CustomAnnotationRequiredFieldResourceInjectionBean {
2213 
2214 		@MyAutowired(optional = false)
2215 		private TestBean testBean;
2216 
2217 		public TestBean getTestBean() {
2218 			return this.testBean;
2219 		}
2220 	}
2221 
2222 
2223 	public static class CustomAnnotationRequiredMethodResourceInjectionBean {
2224 
2225 		private TestBean testBean;
2226 
2227 		@MyAutowired(optional = false)
2228 		public void setTestBean(TestBean testBean) {
2229 			this.testBean = testBean;
2230 		}
2231 
2232 		public TestBean getTestBean() {
2233 			return this.testBean;
2234 		}
2235 	}
2236 
2237 
2238 	public static class CustomAnnotationOptionalFieldResourceInjectionBean extends ResourceInjectionBean {
2239 
2240 		@MyAutowired(optional = true)
2241 		private TestBean testBean3;
2242 
2243 		public TestBean getTestBean3() {
2244 			return this.testBean3;
2245 		}
2246 	}
2247 
2248 
2249 	public static class CustomAnnotationOptionalMethodResourceInjectionBean extends ResourceInjectionBean {
2250 
2251 		private TestBean testBean3;
2252 
2253 		@MyAutowired(optional = true)
2254 		protected void setTestBean3(TestBean testBean3) {
2255 			this.testBean3 = testBean3;
2256 		}
2257 
2258 		public TestBean getTestBean3() {
2259 			return this.testBean3;
2260 		}
2261 	}
2262 
2263 
2264 	@Target({ElementType.METHOD, ElementType.FIELD})
2265 	@Retention(RetentionPolicy.RUNTIME)
2266 	public static @interface MyAutowired {
2267 
2268 		boolean optional() default false;
2269 	}
2270 
2271 
2272 	/**
2273 	 * Bean with a dependency on a {@link FactoryBean}.
2274 	 */
2275 	private static class FactoryBeanDependentBean {
2276 
2277 		@Autowired
2278 		private FactoryBean<?> factoryBean;
2279 
2280 		public final FactoryBean<?> getFactoryBean() {
2281 			return this.factoryBean;
2282 		}
2283 	}
2284 
2285 
2286 	public static class StringFactoryBean implements FactoryBean<String> {
2287 
2288 		@Override
2289 		public String getObject() throws Exception {
2290 			return "";
2291 		}
2292 
2293 		@Override
2294 		public Class<String> getObjectType() {
2295 			return String.class;
2296 		}
2297 
2298 		@Override
2299 		public boolean isSingleton() {
2300 			return true;
2301 		}
2302 	}
2303 
2304 
2305 	public static class OrderedNestedTestBean extends NestedTestBean implements Ordered {
2306 
2307 		private int order;
2308 
2309 		public void setOrder(int order) {
2310 			this.order = order;
2311 		}
2312 
2313 		@Override
2314 		public int getOrder() {
2315 			return this.order;
2316 		}
2317 	}
2318 
2319 
2320 	@Order(1)
2321 	public static class FixedOrder1NestedTestBean extends NestedTestBean {
2322 	}
2323 
2324 	@Order(2)
2325 	public static class FixedOrder2NestedTestBean extends NestedTestBean {
2326 	}
2327 
2328 
2329 	public interface Repository<T> {
2330 	}
2331 
2332 	public static class StringRepository implements Repository<String> {
2333 	}
2334 
2335 	public static class IntegerRepository implements Repository<Integer> {
2336 	}
2337 
2338 	public static class GenericRepository<T> implements Repository<T> {
2339 	}
2340 
2341 	public static class GenericRepositorySubclass extends GenericRepository {
2342 	}
2343 
2344 	public static class SimpleRepository implements Repository {
2345 	}
2346 
2347 	public static class SimpleRepositorySubclass extends SimpleRepository {
2348 	}
2349 
2350 
2351 	public static class RepositoryFactoryBean<T> implements FactoryBean<T> {
2352 
2353 		@Override
2354 		public T getObject() {
2355 			throw new IllegalStateException();
2356 		}
2357 
2358 		@Override
2359 		public Class<?> getObjectType() {
2360 			return Object.class;
2361 		}
2362 
2363 		@Override
2364 		public boolean isSingleton() {
2365 			return false;
2366 		}
2367 	}
2368 
2369 
2370 	public static class RepositoryFieldInjectionBean {
2371 
2372 		@Autowired
2373 		public Repository<String> stringRepository;
2374 
2375 		@Autowired
2376 		public Repository<Integer> integerRepository;
2377 
2378 		@Autowired
2379 		public Repository<String>[] stringRepositoryArray;
2380 
2381 		@Autowired
2382 		public Repository<Integer>[] integerRepositoryArray;
2383 
2384 		@Autowired
2385 		public List<Repository<String>> stringRepositoryList;
2386 
2387 		@Autowired
2388 		public List<Repository<Integer>> integerRepositoryList;
2389 
2390 		@Autowired
2391 		public Map<String, Repository<String>> stringRepositoryMap;
2392 
2393 		@Autowired
2394 		public Map<String, Repository<Integer>> integerRepositoryMap;
2395 	}
2396 
2397 
2398 	public static class RepositoryFieldInjectionBeanWithVariables<S, I> {
2399 
2400 		@Autowired
2401 		public Repository<S> stringRepository;
2402 
2403 		@Autowired
2404 		public Repository<I> integerRepository;
2405 
2406 		@Autowired
2407 		public Repository<S>[] stringRepositoryArray;
2408 
2409 		@Autowired
2410 		public Repository<I>[] integerRepositoryArray;
2411 
2412 		@Autowired
2413 		public List<Repository<S>> stringRepositoryList;
2414 
2415 		@Autowired
2416 		public List<Repository<I>> integerRepositoryList;
2417 
2418 		@Autowired
2419 		public Map<String, Repository<S>> stringRepositoryMap;
2420 
2421 		@Autowired
2422 		public Map<String, Repository<I>> integerRepositoryMap;
2423 	}
2424 
2425 
2426 	public static class RepositoryFieldInjectionBeanWithSubstitutedVariables
2427 			extends RepositoryFieldInjectionBeanWithVariables<String, Integer> {
2428 	}
2429 
2430 
2431 	public static class RepositoryFieldInjectionBeanWithQualifiers {
2432 
2433 		@Autowired @Qualifier("stringRepo")
2434 		public Repository<?> stringRepository;
2435 
2436 		@Autowired @Qualifier("integerRepo")
2437 		public Repository integerRepository;
2438 
2439 		@Autowired @Qualifier("stringRepo")
2440 		public Repository<?>[] stringRepositoryArray;
2441 
2442 		@Autowired @Qualifier("integerRepo")
2443 		public Repository[] integerRepositoryArray;
2444 
2445 		@Autowired @Qualifier("stringRepo")
2446 		public List<Repository> stringRepositoryList;
2447 
2448 		@Autowired @Qualifier("integerRepo")
2449 		public List<Repository<?>> integerRepositoryList;
2450 
2451 		@Autowired @Qualifier("stringRepo")
2452 		public Map<String, Repository<?>> stringRepositoryMap;
2453 
2454 		@Autowired @Qualifier("integerRepo")
2455 		public Map<String, Repository> integerRepositoryMap;
2456 	}
2457 
2458 
2459 	public static class RepositoryFieldInjectionBeanWithSimpleMatch {
2460 
2461 		@Autowired
2462 		public Repository<?> repository;
2463 
2464 		@Autowired
2465 		public Repository<String> stringRepository;
2466 
2467 		@Autowired
2468 		public Repository[] repositoryArray;
2469 
2470 		@Autowired
2471 		public Repository<String>[] stringRepositoryArray;
2472 
2473 		@Autowired
2474 		public List<Repository> repositoryList;
2475 
2476 		@Autowired
2477 		public List<Repository<String>> stringRepositoryList;
2478 
2479 		@Autowired
2480 		public Map<String, Repository<?>> repositoryMap;
2481 
2482 		@Autowired
2483 		public Map<String, Repository<String>> stringRepositoryMap;
2484 	}
2485 
2486 
2487 	public static class RepositoryFactoryBeanInjectionBean {
2488 
2489 		@Autowired
2490 		public RepositoryFactoryBean<?> repositoryFactoryBean;
2491 	}
2492 
2493 
2494 	public static class RepositoryMethodInjectionBean {
2495 
2496 		public Repository<String> stringRepository;
2497 
2498 		public Repository<Integer> integerRepository;
2499 
2500 		public Repository<String>[] stringRepositoryArray;
2501 
2502 		public Repository<Integer>[] integerRepositoryArray;
2503 
2504 		public List<Repository<String>> stringRepositoryList;
2505 
2506 		public List<Repository<Integer>> integerRepositoryList;
2507 
2508 		public Map<String, Repository<String>> stringRepositoryMap;
2509 
2510 		public Map<String, Repository<Integer>> integerRepositoryMap;
2511 
2512 		@Autowired
2513 		public void setStringRepository(Repository<String> stringRepository) {
2514 			this.stringRepository = stringRepository;
2515 		}
2516 
2517 		@Autowired
2518 		public void setIntegerRepository(Repository<Integer> integerRepository) {
2519 			this.integerRepository = integerRepository;
2520 		}
2521 
2522 		@Autowired
2523 		public void setStringRepositoryArray(Repository<String>[] stringRepositoryArray) {
2524 			this.stringRepositoryArray = stringRepositoryArray;
2525 		}
2526 
2527 		@Autowired
2528 		public void setIntegerRepositoryArray(Repository<Integer>[] integerRepositoryArray) {
2529 			this.integerRepositoryArray = integerRepositoryArray;
2530 		}
2531 
2532 		@Autowired
2533 		public void setStringRepositoryList(List<Repository<String>> stringRepositoryList) {
2534 			this.stringRepositoryList = stringRepositoryList;
2535 		}
2536 
2537 		@Autowired
2538 		public void setIntegerRepositoryList(List<Repository<Integer>> integerRepositoryList) {
2539 			this.integerRepositoryList = integerRepositoryList;
2540 		}
2541 
2542 		@Autowired
2543 		public void setStringRepositoryMap(Map<String, Repository<String>> stringRepositoryMap) {
2544 			this.stringRepositoryMap = stringRepositoryMap;
2545 		}
2546 
2547 		@Autowired
2548 		public void setIntegerRepositoryMap(Map<String, Repository<Integer>> integerRepositoryMap) {
2549 			this.integerRepositoryMap = integerRepositoryMap;
2550 		}
2551 	}
2552 
2553 
2554 	public static class RepositoryMethodInjectionBeanWithVariables<S, I> {
2555 
2556 		public Repository<S> stringRepository;
2557 
2558 		public Repository<I> integerRepository;
2559 
2560 		public Repository<S>[] stringRepositoryArray;
2561 
2562 		public Repository<I>[] integerRepositoryArray;
2563 
2564 		public List<Repository<S>> stringRepositoryList;
2565 
2566 		public List<Repository<I>> integerRepositoryList;
2567 
2568 		public Map<String, Repository<S>> stringRepositoryMap;
2569 
2570 		public Map<String, Repository<I>> integerRepositoryMap;
2571 
2572 		@Autowired
2573 		public void setStringRepository(Repository<S> stringRepository) {
2574 			this.stringRepository = stringRepository;
2575 		}
2576 
2577 		@Autowired
2578 		public void setIntegerRepository(Repository<I> integerRepository) {
2579 			this.integerRepository = integerRepository;
2580 		}
2581 
2582 		@Autowired
2583 		public void setStringRepositoryArray(Repository<S>[] stringRepositoryArray) {
2584 			this.stringRepositoryArray = stringRepositoryArray;
2585 		}
2586 
2587 		@Autowired
2588 		public void setIntegerRepositoryArray(Repository<I>[] integerRepositoryArray) {
2589 			this.integerRepositoryArray = integerRepositoryArray;
2590 		}
2591 
2592 		@Autowired
2593 		public void setStringRepositoryList(List<Repository<S>> stringRepositoryList) {
2594 			this.stringRepositoryList = stringRepositoryList;
2595 		}
2596 
2597 		@Autowired
2598 		public void setIntegerRepositoryList(List<Repository<I>> integerRepositoryList) {
2599 			this.integerRepositoryList = integerRepositoryList;
2600 		}
2601 
2602 		@Autowired
2603 		public void setStringRepositoryMap(Map<String, Repository<S>> stringRepositoryMap) {
2604 			this.stringRepositoryMap = stringRepositoryMap;
2605 		}
2606 
2607 		@Autowired
2608 		public void setIntegerRepositoryMap(Map<String, Repository<I>> integerRepositoryMap) {
2609 			this.integerRepositoryMap = integerRepositoryMap;
2610 		}
2611 	}
2612 
2613 
2614 	public static class RepositoryMethodInjectionBeanWithSubstitutedVariables
2615 			extends RepositoryMethodInjectionBeanWithVariables<String, Integer> {
2616 	}
2617 
2618 
2619 	public static class RepositoryConstructorInjectionBean {
2620 
2621 		public Repository<String> stringRepository;
2622 
2623 		public Repository<Integer> integerRepository;
2624 
2625 		public Repository<String>[] stringRepositoryArray;
2626 
2627 		public Repository<Integer>[] integerRepositoryArray;
2628 
2629 		public List<Repository<String>> stringRepositoryList;
2630 
2631 		public List<Repository<Integer>> integerRepositoryList;
2632 
2633 		public Map<String, Repository<String>> stringRepositoryMap;
2634 
2635 		public Map<String, Repository<Integer>> integerRepositoryMap;
2636 
2637 		@Autowired
2638 		public RepositoryConstructorInjectionBean(Repository<String> stringRepository, Repository<Integer> integerRepository,
2639 				Repository<String>[] stringRepositoryArray, Repository<Integer>[] integerRepositoryArray,
2640 				List<Repository<String>> stringRepositoryList, List<Repository<Integer>> integerRepositoryList,
2641 				Map<String, Repository<String>> stringRepositoryMap, Map<String, Repository<Integer>> integerRepositoryMap) {
2642 			this.stringRepository = stringRepository;
2643 			this.integerRepository = integerRepository;
2644 			this.stringRepositoryArray = stringRepositoryArray;
2645 			this.integerRepositoryArray = integerRepositoryArray;
2646 			this.stringRepositoryList = stringRepositoryList;
2647 			this.integerRepositoryList = integerRepositoryList;
2648 			this.stringRepositoryMap = stringRepositoryMap;
2649 			this.integerRepositoryMap = integerRepositoryMap;
2650 		}
2651 	}
2652 
2653 
2654 	/**
2655 	 * Pseudo-implementation of EasyMock's {@code MocksControl} class.
2656 	 */
2657 	public static class MocksControl {
2658 
2659 		@SuppressWarnings("unchecked")
2660 		public <T> T createMock(Class<T> toMock) {
2661 			return (T) Proxy.newProxyInstance(AutowiredAnnotationBeanPostProcessorTests.class.getClassLoader(), new Class<?>[] {toMock},
2662 					new InvocationHandler() {
2663 						@Override
2664 						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
2665 							throw new UnsupportedOperationException("mocked!");
2666 						}
2667 					});
2668 		}
2669 	}
2670 
2671 
2672 	public interface GenericInterface1<T> {
2673 
2674 		public String doSomethingGeneric(T o);
2675 	}
2676 
2677 
2678 	public static class GenericInterface1Impl<T> implements GenericInterface1<T> {
2679 
2680 		@Autowired
2681 		private GenericInterface2<T> gi2;
2682 
2683 		@Override
2684 		public String doSomethingGeneric(T o) {
2685 			return gi2.doSomethingMoreGeneric(o) + "_somethingGeneric_" + o;
2686 		}
2687 
2688 		public static GenericInterface1<String> create() {
2689 			return new StringGenericInterface1Impl();
2690 		}
2691 
2692 		public static GenericInterface1<String> createErased() {
2693 			return new GenericInterface1Impl<String>();
2694 		}
2695 
2696 		public static GenericInterface1 createPlain() {
2697 			return new GenericInterface1Impl();
2698 		}
2699 	}
2700 
2701 
2702 	public static class StringGenericInterface1Impl extends GenericInterface1Impl<String> {
2703 	}
2704 
2705 
2706 	public interface GenericInterface2<K> {
2707 
2708 		public String doSomethingMoreGeneric(K o);
2709 	}
2710 
2711 
2712 	public static class GenericInterface2Impl implements GenericInterface2<String> {
2713 
2714 		@Override
2715 		public String doSomethingMoreGeneric(String o) {
2716 			return "somethingMoreGeneric_" + o;
2717 		}
2718 	}
2719 
2720 
2721 	public static class ReallyGenericInterface2Impl implements GenericInterface2<Object> {
2722 
2723 		@Override
2724 		public String doSomethingMoreGeneric(Object o) {
2725 			return "somethingMoreGeneric_" + o;
2726 		}
2727 	}
2728 
2729 
2730 	public static class PlainGenericInterface2Impl implements GenericInterface2 {
2731 
2732 		@Override
2733 		public String doSomethingMoreGeneric(Object o) {
2734 			return "somethingMoreGeneric_" + o;
2735 		}
2736 	}
2737 
2738 
2739 	public interface StockMovement<P extends StockMovementInstruction> {
2740 	}
2741 
2742 
2743 	public interface StockMovementInstruction<C extends StockMovement> {
2744 	}
2745 
2746 
2747 	public interface StockMovementDao<S extends StockMovement> {
2748 	}
2749 
2750 
2751 	public static class StockMovementImpl<P extends StockMovementInstruction> implements StockMovement<P> {
2752 	}
2753 
2754 
2755 	public static class StockMovementInstructionImpl<C extends StockMovement> implements StockMovementInstruction<C> {
2756 	}
2757 
2758 
2759 	public static class StockMovementDaoImpl<E extends StockMovement> implements StockMovementDao<E> {
2760 	}
2761 
2762 
2763 	public static class StockServiceImpl {
2764 
2765 		@Autowired
2766 		private StockMovementDao<StockMovement> stockMovementDao;
2767 	}
2768 
2769 
2770 	public static class MyCallable implements Callable<Thread> {
2771 
2772 		@Override
2773 		public Thread call() throws Exception {
2774 			return null;
2775 		}
2776 	}
2777 
2778 
2779 	public static class SecondCallable implements Callable<Thread>{
2780 
2781 		@Override
2782 		public Thread call() throws Exception {
2783 			return null;
2784 		}
2785 	}
2786 
2787 
2788 	public static abstract class Foo<T extends Runnable, RT extends Callable<T>> {
2789 
2790 		private RT obj;
2791 
2792 		protected void setObj(RT obj) {
2793 			if (this.obj != null) {
2794 				throw new IllegalStateException("Already called");
2795 			}
2796 			this.obj = obj;
2797 		}
2798 	}
2799 
2800 
2801 	public static class FooBar extends Foo<Thread, MyCallable> {
2802 
2803 		@Override
2804 		@Autowired
2805 		public void setObj(MyCallable obj) {
2806 			super.setObj(obj);
2807 		}
2808 	}
2809 
2810 }