Skip to content

Commit d44bc27

Browse files
committed
Avoid FactoryBean initialization on isSingleton check for decorated bean definition
Issue: SPR-14892 Issue: SPR-15042 (cherry picked from commit 209e7a7)
1 parent 243e21a commit d44bc27

File tree

6 files changed

+97
-30
lines changed

6 files changed

+97
-30
lines changed

spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,24 @@
2929

3030
/**
3131
* @author Mark Fisher
32-
* @author Chris Beams
3332
* @author Juergen Hoeller
33+
* @author Chris Beams
3434
*/
3535
public class ScopedProxyAutowireTests {
3636

37-
private static final Class<?> CLASS = ScopedProxyAutowireTests.class;
38-
39-
private static final Resource SCOPED_AUTOWIRE_TRUE_CONTEXT = qualifiedResource(CLASS, "scopedAutowireTrue.xml");
40-
private static final Resource SCOPED_AUTOWIRE_FALSE_CONTEXT = qualifiedResource(CLASS, "scopedAutowireFalse.xml");
37+
private static final Resource SCOPED_AUTOWIRE_FALSE_CONTEXT =
38+
qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireFalse.xml");
39+
private static final Resource SCOPED_AUTOWIRE_TRUE_CONTEXT =
40+
qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireTrue.xml");
4141

4242

4343
@Test
4444
public void testScopedProxyInheritsAutowireCandidateFalse() {
4545
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
4646
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_FALSE_CONTEXT);
4747
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
48+
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
49+
assertFalse(bf.containsSingleton("scoped"));
4850
TestBean autowired = (TestBean) bf.getBean("autowired");
4951
TestBean unscoped = (TestBean) bf.getBean("unscoped");
5052
assertSame(unscoped, autowired.getChild());
@@ -54,7 +56,9 @@ public void testScopedProxyInheritsAutowireCandidateFalse() {
5456
public void testScopedProxyReplacesAutowireCandidateTrue() {
5557
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
5658
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_TRUE_CONTEXT);
59+
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
5760
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
61+
assertFalse(bf.containsSingleton("scoped"));
5862
TestBean autowired = (TestBean) bf.getBean("autowired");
5963
TestBean scoped = (TestBean) bf.getBean("scoped");
6064
assertSame(scoped, autowired.getChild());
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<config xmlns="http://www.springframework.org/schema/aop"
2-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
44

55
<pointcut id="testPointcut" expression="execution(* foo(..)) and within(springbank.dao.AccountDao+)"/>
66
<pointcut id="testPointcut1" expression="execution(* springbank.dao.AccountDao.foo(..))"/>
@@ -9,4 +9,4 @@
99
<after method="foo" pointcut-ref="testPointcut"/>
1010
</aspect>
1111

12-
</config>
12+
</config>
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<beans xmlns="http://www.springframework.org/schema/beans"
3-
xmlns:aop="http://www.springframework.org/schema/aop"
4-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
6-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
3+
xmlns:aop="http://www.springframework.org/schema/aop"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
6+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
77

8-
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false">
9-
<aop:scoped-proxy/>
10-
</bean>
8+
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" scope="prototype" autowire-candidate="false">
9+
<aop:scoped-proxy/>
10+
</bean>
1111

12-
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true"/>
12+
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true"/>
1313

14-
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
14+
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
1515

1616
</beans>
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<beans xmlns="http://www.springframework.org/schema/beans"
3-
xmlns:aop="http://www.springframework.org/schema/aop"
4-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
6-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
3+
xmlns:aop="http://www.springframework.org/schema/aop"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
6+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
77

8-
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true">
9-
<aop:scoped-proxy/>
10-
</bean>
8+
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" scope="singleton" autowire-candidate="true">
9+
<aop:scoped-proxy/>
10+
</bean>
1111

12-
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false"/>
12+
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false"/>
1313

14-
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
14+
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
1515

1616
</beans>

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,12 @@ private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSi
423423
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
424424
// In case of FactoryBean, match object created by FactoryBean.
425425
boolean isFactoryBean = isFactoryBean(beanName, mbd);
426-
boolean matchFound = (allowEagerInit || !isFactoryBean ||
427-
(mbd.getDecoratedDefinition() != null && !mbd.isLazyInit()) ||
428-
containsSingleton(beanName)) &&
429-
(includeNonSingletons || isSingleton(beanName)) &&
426+
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
427+
boolean matchFound =
428+
(allowEagerInit || !isFactoryBean ||
429+
(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
430+
(includeNonSingletons ||
431+
(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
430432
isTypeMatch(beanName, type);
431433
if (!matchFound && isFactoryBean) {
432434
// In case of FactoryBean, try to match FactoryBean instance itself next.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2002-2016 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.context.annotation;
18+
19+
import org.junit.Test;
20+
21+
import org.springframework.aop.framework.ProxyFactoryBean;
22+
import org.springframework.aop.target.CommonsPool2TargetSource;
23+
24+
/**
25+
* @author Juergen Hoeller
26+
*/
27+
public class Spr15042Tests {
28+
29+
@Test
30+
public void poolingTargetSource() {
31+
new AnnotationConfigApplicationContext(PoolingTargetSourceConfig.class);
32+
}
33+
34+
35+
@Configuration
36+
static class PoolingTargetSourceConfig {
37+
38+
@Bean
39+
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
40+
public ProxyFactoryBean myObject() {
41+
ProxyFactoryBean pfb = new ProxyFactoryBean();
42+
pfb.setTargetSource(poolTargetSource());
43+
return pfb;
44+
}
45+
46+
@Bean
47+
public CommonsPool2TargetSource poolTargetSource() {
48+
CommonsPool2TargetSource pool = new CommonsPool2TargetSource();
49+
pool.setMaxSize(3);
50+
pool.setTargetBeanName("myObjectTarget");
51+
return pool;
52+
}
53+
54+
@Bean(name = "myObjectTarget")
55+
@Scope(scopeName = "prototype")
56+
public Object myObjectTarget() {
57+
return new Object();
58+
}
59+
}
60+
61+
}

0 commit comments

Comments
 (0)