Skip to content

Commit 1bd775f

Browse files
committed
@Autowired-driven ObjectFactory/Provider resolution works in non-singleton beans as well
Issue: SPR-9181
1 parent 68c5f20 commit 1bd775f

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ public DependencyDescriptor(Field field, boolean required, boolean eager) {
121121
this.eager = eager;
122122
}
123123

124+
/**
125+
* Copy constructor.
126+
* @param original the original descriptor to create a copy from
127+
*/
128+
public DependencyDescriptor(DependencyDescriptor original) {
129+
this.methodParameter = original.methodParameter;
130+
this.field = original.field;
131+
this.declaringClass = original.declaringClass;
132+
this.methodName = original.methodName;
133+
this.parameterTypes = original.parameterTypes;
134+
this.parameterIndex = original.parameterIndex;
135+
this.fieldName = original.fieldName;
136+
this.required = original.required;
137+
this.eager = original.eager;
138+
this.nestingLevel = original.nestingLevel;
139+
this.fieldAnnotations = original.fieldAnnotations;
140+
}
141+
124142

125143
/**
126144
* Return the wrapped MethodParameter, if any.
@@ -156,6 +174,10 @@ public boolean isEager() {
156174
}
157175

158176

177+
/**
178+
* Increase this descriptor's nesting level.
179+
* @see MethodParameter#increaseNestingLevel()
180+
*/
159181
public void increaseNestingLevel() {
160182
this.nestingLevel++;
161183
if (this.methodParameter != null) {

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@
2121
import java.io.ObjectInputStream;
2222
import java.io.ObjectStreamException;
2323
import java.io.Serializable;
24-
2524
import java.lang.annotation.Annotation;
2625
import java.lang.ref.Reference;
2726
import java.lang.ref.WeakReference;
28-
2927
import java.security.AccessController;
3028
import java.security.PrivilegedAction;
31-
3229
import java.util.ArrayList;
3330
import java.util.Arrays;
3431
import java.util.Collection;
@@ -39,7 +36,6 @@
3936
import java.util.Map;
4037
import java.util.Set;
4138
import java.util.concurrent.ConcurrentHashMap;
42-
4339
import javax.inject.Provider;
4440

4541
import org.springframework.beans.BeansException;
@@ -1031,9 +1027,9 @@ private class DependencyObjectFactory implements ObjectFactory<Object>, Serializ
10311027
private final String beanName;
10321028

10331029
public DependencyObjectFactory(DependencyDescriptor descriptor, String beanName) {
1034-
this.descriptor = descriptor;
1035-
this.beanName = beanName;
1030+
this.descriptor = new DependencyDescriptor(descriptor);
10361031
this.descriptor.increaseNestingLevel();
1032+
this.beanName = beanName;
10371033
}
10381034

10391035
public Object getObject() throws BeansException {

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.util.List;
2525
import java.util.Map;
2626

27-
import static org.junit.Assert.*;
2827
import org.junit.Test;
2928
import test.beans.ITestBean;
3029
import test.beans.IndexedTestBean;
@@ -42,6 +41,8 @@
4241
import org.springframework.beans.factory.support.RootBeanDefinition;
4342
import org.springframework.util.SerializationTestUtils;
4443

44+
import static org.junit.Assert.*;
45+
4546
/**
4647
* Unit tests for {@link AutowiredAnnotationBeanPostProcessor}.
4748
*
@@ -601,6 +602,22 @@ public void testObjectFactoryInjection() {
601602
bf.destroySingletons();
602603
}
603604

605+
@Test
606+
public void testObjectFactoryInjectionIntoPrototypeBean() {
607+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
608+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
609+
bpp.setBeanFactory(bf);
610+
bf.addBeanPostProcessor(bpp);
611+
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryInjectionBean.class, false));
612+
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
613+
614+
ObjectFactoryInjectionBean bean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
615+
assertSame(bf.getBean("testBean"), bean.getTestBean());
616+
ObjectFactoryInjectionBean anotherBean = (ObjectFactoryInjectionBean) bf.getBean("annotatedBean");
617+
assertNotSame(anotherBean, bean);
618+
assertSame(bf.getBean("testBean"), anotherBean.getTestBean());
619+
}
620+
604621
@Test
605622
public void testObjectFactoryQualifierInjection() {
606623
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();

spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,26 @@ public void testObjectFactoryInjection() {
383383
bf.destroySingletons();
384384
}
385385

386+
@Test
387+
public void testObjectFactoryInjectionIntoPrototypeBean() {
388+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
389+
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
390+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
391+
bpp.setBeanFactory(bf);
392+
bf.addBeanPostProcessor(bpp);
393+
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryQualifierInjectionBean.class, false));
394+
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
395+
bd.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "testBean"));
396+
bf.registerBeanDefinition("testBean", bd);
397+
bf.registerBeanDefinition("testBean2", new RootBeanDefinition(TestBean.class));
398+
399+
ObjectFactoryQualifierInjectionBean bean = (ObjectFactoryQualifierInjectionBean) bf.getBean("annotatedBean");
400+
assertSame(bf.getBean("testBean"), bean.getTestBean());
401+
ObjectFactoryQualifierInjectionBean anotherBean = (ObjectFactoryQualifierInjectionBean) bf.getBean("annotatedBean");
402+
assertNotSame(anotherBean, bean);
403+
assertSame(bf.getBean("testBean"), bean.getTestBean());
404+
}
405+
386406
@Test
387407
public void testObjectFactoryQualifierInjection() {
388408
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();

0 commit comments

Comments
 (0)