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 faf0355fd5..56ba95b68e 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-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -79,7 +80,12 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat } @Override public Object getTarget() { - return beanFactory.doResolveDependency(descriptor, beanName, null, null); + Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null); + if (target == null) { + throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(), + "Optional dependency not present for lazy injection point"); + } + return target; } @Override public void releaseTarget(Object target) { 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 043ed736e7..9c123a41b5 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-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -118,6 +118,28 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { } } + @Test + public void testLazyOptionalResourceInjectionWithNonExistingTarget() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + RootBeanDefinition bd = new RootBeanDefinition(OptionalFieldResourceInjectionBean.class); + bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + bf.registerBeanDefinition("annotatedBean", bd); + + OptionalFieldResourceInjectionBean bean = (OptionalFieldResourceInjectionBean) bf.getBean("annotatedBean"); + assertNotNull(bean.getTestBean()); + try { + bean.getTestBean().getName(); + fail("Should have thrown NoSuchBeanDefinitionException"); + } + catch (NoSuchBeanDefinitionException ex) { + // expected; + } + } + public interface TestBeanHolder { @@ -136,6 +158,17 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests { } + public static class OptionalFieldResourceInjectionBean implements TestBeanHolder { + + @Autowired(required = false) @Lazy + private TestBean testBean; + + public TestBean getTestBean() { + return this.testBean; + } + } + + public static class FieldResourceInjectionBeanWithCompositeAnnotation implements TestBeanHolder { @LazyInject