Skip to content

Commit b9935e9

Browse files
committed
BeanFactoryAnnotationUtils consistently applies bean name fallback when no BeanDefinition present
Issue: SPR-11915 (cherry picked from commit f8b6114)
1 parent 86ea305 commit b9935e9

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
* Spring's {@link Qualifier @Qualifier} annotation.
3535
*
3636
* @author Chris Beams
37+
* @author Juergen Hoeller
3738
* @since 3.1.2
3839
* @see BeanFactoryUtils
3940
*/
@@ -90,9 +91,13 @@ private static <T> T qualifiedBeanOfType(ConfigurableListableBeanFactory bf, Cla
9091
if (matchingBean != null) {
9192
return matchingBean;
9293
}
94+
else if (bf.containsBean(qualifier)) {
95+
// Fallback: target bean at least found by bean name - probably a manually registered singleton.
96+
return bf.getBean(qualifier, beanType);
97+
}
9398
else {
9499
throw new NoSuchBeanDefinitionException(qualifier, "No matching " + beanType.getSimpleName() +
95-
" bean found for qualifier '" + qualifier + "' - neither qualifier " + "match nor bean name match!");
100+
" bean found for qualifier '" + qualifier + "' - neither qualifier match nor bean name match!");
96101
}
97102
}
98103

@@ -128,7 +133,7 @@ private static boolean isQualifierMatch(String qualifier, String beanName, Confi
128133
}
129134
}
130135
catch (NoSuchBeanDefinitionException ex) {
131-
// ignore - can't compare qualifiers for a manually registered singleton object
136+
// Ignore - can't compare qualifiers for a manually registered singleton object
132137
}
133138
}
134139
return false;

spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionNamespaceHandlerTests.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ protected void tearDown() {
5555
public void testIsProxy() throws Exception {
5656
TransactionalTestBean bean = getTestBean();
5757
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
58-
Map services = this.context.getBeansWithAnnotation(Service.class);
58+
Map<String, Object> services = this.context.getBeansWithAnnotation(Service.class);
5959
assertTrue("Stereotype annotation not visible", services.containsKey("testBean"));
6060
}
6161

@@ -110,14 +110,18 @@ private TransactionalTestBean getTestBean() {
110110
public static class TransactionalTestBean {
111111

112112
@Transactional(readOnly = true)
113-
public Collection findAllFoos() {
113+
public Collection<?> findAllFoos() {
114114
return null;
115115
}
116116

117117
@Transactional
118118
public void saveFoo() {
119119
}
120120

121+
@Transactional("qualifiedTransactionManager")
122+
public void saveQualifiedFoo() {
123+
}
124+
121125
@Transactional
122126
public void exceptional(Throwable t) throws Throwable {
123127
throw t;

spring-tx/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementTests.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
2121
import org.junit.Test;
2222

2323
import org.springframework.aop.support.AopUtils;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.context.ConfigurableApplicationContext;
2426
import org.springframework.context.annotation.AdviceMode;
2527
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2628
import org.springframework.context.annotation.Bean;
@@ -33,10 +35,13 @@
3335
import static org.hamcrest.CoreMatchers.*;
3436
import static org.junit.Assert.*;
3537

38+
import javax.annotation.PostConstruct;
39+
3640
/**
3741
* Tests demonstrating use of @EnableTransactionManagement @Configuration classes.
3842
*
3943
* @author Chris Beams
44+
* @author Stephane Nicoll
4045
* @since 3.1
4146
*/
4247
public class EnableTransactionManagementTests {
@@ -101,6 +106,21 @@ public void proxyTypeAspectJCausesRegistrationOfAnnotationTransactionAspect() {
101106
}
102107
}
103108

109+
@Test
110+
public void spr11915() {
111+
AnnotationConfigApplicationContext ctx =
112+
new AnnotationConfigApplicationContext(Spr11915Config.class);
113+
114+
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
115+
bean.saveQualifiedFoo();
116+
117+
CallCountingTransactionManager txManager = ctx
118+
.getBean("qualifiedTransactionManager", CallCountingTransactionManager.class);
119+
assertThat(txManager.begun, equalTo(1));
120+
assertThat(txManager.commits, equalTo(1));
121+
assertThat(txManager.rollbacks, equalTo(0));
122+
}
123+
104124

105125
@Configuration
106126
@EnableTransactionManagement
@@ -118,6 +138,25 @@ static class InheritedEnableTxConfig extends EnableTxConfig {
118138
static class EnableAspectJTxConfig {
119139
}
120140

141+
@Configuration
142+
@EnableTransactionManagement
143+
static class Spr11915Config {
144+
145+
@Autowired
146+
private ConfigurableApplicationContext applicationContext;
147+
148+
@PostConstruct
149+
public void initializeApp() {
150+
applicationContext.getBeanFactory().registerSingleton(
151+
"qualifiedTransactionManager", new CallCountingTransactionManager());
152+
}
153+
154+
@Bean
155+
public TransactionalTestBean testBean() {
156+
return new TransactionalTestBean();
157+
}
158+
}
159+
121160

122161
@Configuration
123162
static class TxManagerConfig {

0 commit comments

Comments
 (0)