diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java index 785ada6c5e0..407ed930f3d 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,11 @@ package org.springframework.context.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; @@ -82,6 +87,16 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat public Object getTarget() { Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null); if (target == null) { + Class type = getTargetClass(); + if (Map.class == type) { + return Collections.EMPTY_MAP; + } + else if (List.class == type) { + return Collections.EMPTY_LIST; + } + else if (Set.class == type || Collection.class == type) { + return Collections.EMPTY_SET; + } throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(), "Optional dependency not present for lazy injection point"); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/LazyAutowiredAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/LazyAutowiredAnnotationBeanPostProcessorTests.java index 9c123a41b57..9306a810a94 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/LazyAutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/LazyAutowiredAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.context.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; import org.junit.Test; @@ -59,6 +60,24 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { @Test public void testLazyResourceInjectionWithField() { doTestLazyResourceInjection(FieldResourceInjectionBean.class); + + AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); + RootBeanDefinition abd = new RootBeanDefinition(FieldResourceInjectionBean.class); + abd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + ac.registerBeanDefinition("annotatedBean", abd); + RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class); + tbd.setLazyInit(true); + ac.registerBeanDefinition("testBean", tbd); + ac.refresh(); + + FieldResourceInjectionBean bean = ac.getBean("annotatedBean", FieldResourceInjectionBean.class); + assertFalse(ac.getBeanFactory().containsSingleton("testBean")); + assertFalse(bean.getTestBeans().isEmpty()); + assertNull(bean.getTestBeans().get(0).getName()); + assertTrue(ac.getBeanFactory().containsSingleton("testBean")); + TestBean tb = (TestBean) ac.getBean("testBean"); + tb.setName("tb"); + assertSame("tb", bean.getTestBean().getName()); } @Test @@ -114,7 +133,7 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { fail("Should have thrown NoSuchBeanDefinitionException"); } catch (NoSuchBeanDefinitionException ex) { - // expected; + // expected } } @@ -131,12 +150,14 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { OptionalFieldResourceInjectionBean bean = (OptionalFieldResourceInjectionBean) bf.getBean("annotatedBean"); assertNotNull(bean.getTestBean()); + assertNotNull(bean.getTestBeans()); + assertTrue(bean.getTestBeans().isEmpty()); try { bean.getTestBean().getName(); fail("Should have thrown NoSuchBeanDefinitionException"); } catch (NoSuchBeanDefinitionException ex) { - // expected; + // expected } } @@ -152,9 +173,16 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { @Autowired @Lazy private TestBean testBean; + @Autowired @Lazy + private List testBeans; + public TestBean getTestBean() { return this.testBean; } + + public List getTestBeans() { + return testBeans; + } } @@ -163,9 +191,16 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { @Autowired(required = false) @Lazy private TestBean testBean; + @Autowired(required = false) @Lazy + private List testBeans; + public TestBean getTestBean() { return this.testBean; } + + public List getTestBeans() { + return this.testBeans; + } }