ImportRegistry properly tracks excluded superclasses
Issue: SPR-14972
This commit is contained in:
@@ -129,7 +129,7 @@ class ConfigurationClassBeanDefinitionReader {
|
|||||||
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
|
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
|
||||||
this.registry.removeBeanDefinition(beanName);
|
this.registry.removeBeanDefinition(beanName);
|
||||||
}
|
}
|
||||||
this.importRegistry.removeImportingClassFor(configClass.getMetadata().getClassName());
|
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -643,23 +643,24 @@ class ConfigurationClassParser {
|
|||||||
this.imports.add(importedClass, importingClass);
|
this.imports.add(importedClass, importingClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeImportingClassFor(String importedClass) {
|
|
||||||
for (List<AnnotationMetadata> list : this.imports.values()) {
|
|
||||||
for (Iterator<AnnotationMetadata> iterator = list.iterator(); iterator.hasNext();) {
|
|
||||||
if (iterator.next().getClassName().equals(importedClass)) {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationMetadata getImportingClassFor(String importedClass) {
|
public AnnotationMetadata getImportingClassFor(String importedClass) {
|
||||||
List<AnnotationMetadata> list = this.imports.get(importedClass);
|
List<AnnotationMetadata> list = this.imports.get(importedClass);
|
||||||
return (!CollectionUtils.isEmpty(list) ? list.get(list.size() - 1) : null);
|
return (!CollectionUtils.isEmpty(list) ? list.get(list.size() - 1) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeImportingClass(String importingClass) {
|
||||||
|
for (List<AnnotationMetadata> list : this.imports.values()) {
|
||||||
|
for (Iterator<AnnotationMetadata> iterator = list.iterator(); iterator.hasNext();) {
|
||||||
|
if (iterator.next().getClassName().equals(importingClass)) {
|
||||||
|
iterator.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a stack containing (in order)
|
* Given a stack containing (in order)
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -38,7 +38,7 @@ public interface ConfigurationCondition extends Condition {
|
|||||||
/**
|
/**
|
||||||
* The various configuration phases where the condition could be evaluated.
|
* The various configuration phases where the condition could be evaluated.
|
||||||
*/
|
*/
|
||||||
public static enum ConfigurationPhase {
|
enum ConfigurationPhase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Condition} should be evaluated as a {@code @Configuration}
|
* The {@link Condition} should be evaluated as a {@code @Configuration}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -26,6 +26,6 @@ interface ImportRegistry {
|
|||||||
|
|
||||||
AnnotationMetadata getImportingClassFor(String importedClass);
|
AnnotationMetadata getImportingClassFor(String importedClass);
|
||||||
|
|
||||||
void removeImportingClassFor(String importedClass);
|
void removeImportingClass(String importingClass);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ import org.springframework.context.ConfigurableApplicationContext;
|
|||||||
import org.springframework.context.annotation.AdviceMode;
|
import org.springframework.context.annotation.AdviceMode;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.ConfigurationCondition;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.tests.transaction.CallCountingTransactionManager;
|
import org.springframework.tests.transaction.CallCountingTransactionManager;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
@@ -49,7 +53,8 @@ public class EnableTransactionManagementTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionProxyIsCreated() {
|
public void transactionProxyIsCreated() {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, TxManagerConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||||
|
EnableTxConfig.class, TxManagerConfig.class);
|
||||||
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
||||||
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
|
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
|
||||||
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
|
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
|
||||||
@@ -59,7 +64,19 @@ public class EnableTransactionManagementTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionProxyIsCreatedWithEnableOnSuperclass() {
|
public void transactionProxyIsCreatedWithEnableOnSuperclass() {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(InheritedEnableTxConfig.class, TxManagerConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||||
|
InheritedEnableTxConfig.class, TxManagerConfig.class);
|
||||||
|
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
||||||
|
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
|
||||||
|
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
|
||||||
|
assertTrue("Stereotype annotation not visible", services.containsKey("testBean"));
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transactionProxyIsCreatedWithEnableOnExcludedSuperclass() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||||
|
ParentEnableTxConfig.class, ChildEnableTxConfig.class, TxManagerConfig.class);
|
||||||
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
||||||
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
|
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
|
||||||
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
|
Map<?,?> services = ctx.getBeansWithAnnotation(Service.class);
|
||||||
@@ -69,7 +86,8 @@ public class EnableTransactionManagementTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void txManagerIsResolvedOnInvocationOfTransactionalMethod() {
|
public void txManagerIsResolvedOnInvocationOfTransactionalMethod() {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, TxManagerConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||||
|
EnableTxConfig.class, TxManagerConfig.class);
|
||||||
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
||||||
|
|
||||||
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
|
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
|
||||||
@@ -79,7 +97,8 @@ public class EnableTransactionManagementTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void txManagerIsResolvedCorrectlyWhenMultipleManagersArePresent() {
|
public void txManagerIsResolvedCorrectlyWhenMultipleManagersArePresent() {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EnableTxConfig.class, MultiTxManagerConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||||
|
EnableTxConfig.class, MultiTxManagerConfig.class);
|
||||||
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
|
||||||
|
|
||||||
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
|
// invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
|
||||||
@@ -95,7 +114,7 @@ public class EnableTransactionManagementTests {
|
|||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public void proxyTypeAspectJCausesRegistrationOfAnnotationTransactionAspect() {
|
public void proxyTypeAspectJCausesRegistrationOfAnnotationTransactionAspect() {
|
||||||
try {
|
try {
|
||||||
new AnnotationConfigApplicationContext(EnableAspectJTxConfig.class, TxManagerConfig.class);
|
new AnnotationConfigApplicationContext(EnableAspectjTxConfig.class, TxManagerConfig.class);
|
||||||
fail("should have thrown CNFE when trying to load AnnotationTransactionAspect. " +
|
fail("should have thrown CNFE when trying to load AnnotationTransactionAspect. " +
|
||||||
"Do you actually have org.springframework.aspects on the classpath?");
|
"Do you actually have org.springframework.aspects on the classpath?");
|
||||||
}
|
}
|
||||||
@@ -137,15 +156,54 @@ public class EnableTransactionManagementTests {
|
|||||||
static class EnableTxConfig {
|
static class EnableTxConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class InheritedEnableTxConfig extends EnableTxConfig {
|
static class InheritedEnableTxConfig extends EnableTxConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
|
@EnableTransactionManagement
|
||||||
static class EnableAspectJTxConfig {
|
@Conditional(NeverCondition.class)
|
||||||
|
static class ParentEnableTxConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
Object someBean() {
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class ChildEnableTxConfig extends ParentEnableTxConfig {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Object someBean() {
|
||||||
|
return "X";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class NeverCondition implements ConfigurationCondition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationPhase getConfigurationPhase() {
|
||||||
|
return ConfigurationPhase.REGISTER_BEAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
|
||||||
|
static class EnableAspectjTxConfig {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
static class Spr11915Config {
|
static class Spr11915Config {
|
||||||
@@ -162,6 +220,7 @@ public class EnableTransactionManagementTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class TxManagerConfig {
|
static class TxManagerConfig {
|
||||||
|
|
||||||
@@ -174,9 +233,9 @@ public class EnableTransactionManagementTests {
|
|||||||
public PlatformTransactionManager txManager() {
|
public PlatformTransactionManager txManager() {
|
||||||
return new CallCountingTransactionManager();
|
return new CallCountingTransactionManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class MultiTxManagerConfig extends TxManagerConfig implements TransactionManagementConfigurer {
|
static class MultiTxManagerConfig extends TxManagerConfig implements TransactionManagementConfigurer {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user