Skip to content

Commit c732f38

Browse files
committed
ImportRegistry properly tracks excluded superclasses
Issue: SPR-14972 (cherry picked from commit dd3c370)
1 parent 3556d4b commit c732f38

File tree

5 files changed

+81
-21
lines changed

5 files changed

+81
-21
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configC
129129
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
130130
this.registry.removeBeanDefinition(beanName);
131131
}
132-
this.importRegistry.removeImportingClassFor(configClass.getMetadata().getClassName());
132+
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
133133
return;
134134
}
135135

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -652,22 +652,23 @@ public void registerImport(AnnotationMetadata importingClass, String importedCla
652652
}
653653

654654
@Override
655-
public void removeImportingClassFor(String importedClass) {
655+
public AnnotationMetadata getImportingClassFor(String importedClass) {
656+
List<AnnotationMetadata> list = this.imports.get(importedClass);
657+
return (!CollectionUtils.isEmpty(list) ? list.get(list.size() - 1) : null);
658+
}
659+
660+
@Override
661+
public void removeImportingClass(String importingClass) {
656662
for (List<AnnotationMetadata> list : this.imports.values()) {
657663
for (Iterator<AnnotationMetadata> iterator = list.iterator(); iterator.hasNext();) {
658-
if (iterator.next().getClassName().equals(importedClass)) {
664+
if (iterator.next().getClassName().equals(importingClass)) {
659665
iterator.remove();
666+
break;
660667
}
661668
}
662669
}
663670
}
664671

665-
@Override
666-
public AnnotationMetadata getImportingClassFor(String importedClass) {
667-
List<AnnotationMetadata> list = this.imports.get(importedClass);
668-
return (!CollectionUtils.isEmpty(list) ? list.get(list.size() - 1) : null);
669-
}
670-
671672
/**
672673
* Given a stack containing (in order)
673674
* <ul>

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationCondition.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -38,7 +38,7 @@ public interface ConfigurationCondition extends Condition {
3838
/**
3939
* The various configuration phases where the condition could be evaluated.
4040
*/
41-
public static enum ConfigurationPhase {
41+
enum ConfigurationPhase {
4242

4343
/**
4444
* The {@link Condition} should be evaluated as a {@code @Configuration}

spring-context/src/main/java/org/springframework/context/annotation/ImportRegistry.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -26,6 +26,6 @@ interface ImportRegistry {
2626

2727
AnnotationMetadata getImportingClassFor(String importedClass);
2828

29-
void removeImportingClassFor(String importedClass);
29+
void removeImportingClass(String importingClass);
3030

3131
}

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

+67-8
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828
import org.springframework.context.annotation.AdviceMode;
2929
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3030
import org.springframework.context.annotation.Bean;
31+
import org.springframework.context.annotation.ConditionContext;
32+
import org.springframework.context.annotation.Conditional;
3133
import org.springframework.context.annotation.Configuration;
34+
import org.springframework.context.annotation.ConfigurationCondition;
35+
import org.springframework.core.type.AnnotatedTypeMetadata;
3236
import org.springframework.stereotype.Service;
3337
import org.springframework.tests.transaction.CallCountingTransactionManager;
3438
import org.springframework.transaction.PlatformTransactionManager;
@@ -51,7 +55,8 @@ public class EnableTransactionManagementTests {
5155

5256
@Test
5357
public void transactionProxyIsCreated() {
54-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, TxManagerConfig.class);
58+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
59+
EnableTxConfig.class, TxManagerConfig.class);
5560
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
5661
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
5762
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
@@ -61,7 +66,19 @@ public void transactionProxyIsCreated() {
6166

6267
@Test
6368
public void transactionProxyIsCreatedWithEnableOnSuperclass() {
64-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(InheritedEnableTxConfig.class, TxManagerConfig.class);
69+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
70+
InheritedEnableTxConfig.class, TxManagerConfig.class);
71+
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
72+
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
73+
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
74+
assertTrue("Stereotype annotation not visible", services.containsKey("testBean"));
75+
ctx.close();
76+
}
77+
78+
@Test
79+
public void transactionProxyIsCreatedWithEnableOnExcludedSuperclass() {
80+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
81+
ParentEnableTxConfig.class, ChildEnableTxConfig.class, TxManagerConfig.class);
6582
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
6683
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
6784
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
@@ -71,7 +88,8 @@ public void transactionProxyIsCreatedWithEnableOnSuperclass() {
7188

7289
@Test
7390
public void txManagerIsResolvedOnInvocationOfTransactionalMethod() {
74-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, TxManagerConfig.class);
91+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
92+
EnableTxConfig.class, TxManagerConfig.class);
7593
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
7694

7795
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
@@ -81,7 +99,8 @@ public void txManagerIsResolvedOnInvocationOfTransactionalMethod() {
8199

82100
@Test
83101
public void txManagerIsResolvedCorrectlyWhenMultipleManagersArePresent() {
84-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, MultiTxManagerConfig.class);
102+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
103+
EnableTxConfig.class, MultiTxManagerConfig.class);
85104
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
86105

87106
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
@@ -96,7 +115,7 @@ public void txManagerIsResolvedCorrectlyWhenMultipleManagersArePresent() {
96115
@Test
97116
public void proxyTypeAspectJCausesRegistrationOfAnnotationTransactionAspect() {
98117
try {
99-
new AnnotationConfigApplicationContext(EnableAspectJTxConfig.class, TxManagerConfig.class);
118+
new AnnotationConfigApplicationContext(EnableAspectjTxConfig.class, TxManagerConfig.class);
100119
fail("should have thrown CNFE when trying to load AnnotationTransactionAspect. " +
101120
"Do you actually have org.springframework.aspects on the classpath?");
102121
}
@@ -138,15 +157,54 @@ public void spr11915() {
138157
static class EnableTxConfig {
139158
}
140159

160+
141161
@Configuration
142162
static class InheritedEnableTxConfig extends EnableTxConfig {
143163
}
144164

165+
166+
@Configuration
167+
@EnableTransactionManagement
168+
@Conditional(NeverCondition.class)
169+
static class ParentEnableTxConfig {
170+
171+
@Bean
172+
Object someBean() {
173+
return new Object();
174+
}
175+
}
176+
177+
178+
@Configuration
179+
static class ChildEnableTxConfig extends ParentEnableTxConfig {
180+
181+
@Override
182+
Object someBean() {
183+
return "X";
184+
}
185+
}
186+
187+
188+
private static class NeverCondition implements ConfigurationCondition {
189+
190+
@Override
191+
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
192+
return false;
193+
}
194+
195+
@Override
196+
public ConfigurationPhase getConfigurationPhase() {
197+
return ConfigurationPhase.REGISTER_BEAN;
198+
}
199+
}
200+
201+
145202
@Configuration
146-
@EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
147-
static class EnableAspectJTxConfig {
203+
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
204+
static class EnableAspectjTxConfig {
148205
}
149206

207+
150208
@Configuration
151209
@EnableTransactionManagement
152210
static class Spr11915Config {
@@ -166,6 +224,7 @@ public TransactionalTestBean testBean() {
166224
}
167225
}
168226

227+
169228
@Configuration
170229
static class TxManagerConfig {
171230

@@ -178,9 +237,9 @@ public TransactionalTestBean testBean() {
178237
public PlatformTransactionManager txManager() {
179238
return new CallCountingTransactionManager();
180239
}
181-
182240
}
183241

242+
184243
@Configuration
185244
static class MultiTxManagerConfig extends TxManagerConfig implements TransactionManagementConfigurer {
186245

0 commit comments

Comments
 (0)