Refactor ImportSelector support
Separate concerns of @Configuration class selection from the need to register certain infrastructure beans such as auto proxy creators. Prior to this change, ImportSelector implementations were responsible for both of these concerns, leading to awkwardness and duplication. Also introduced in this change is ImportBeanDefinitionRegistrar and two implementations, AutoProxyRegistrar and AspectJAutoProxyRegistrar. See the refactored implementations of CachingConfigurationSelector, TransactionManagementConfigurationSelector to see the former; AspectJAutoProxyConfigurationSelector to see the latter. ImportSelector and ImportBeanDefinitionRegistrar are both handled as special-case arguments to the @Import annotation within ConfigurationClassParser. These refactorings are important because they ensure that Spring users will be able to understand and extend existing @Enable* annotations and their backing ImportSelector and @Configuration classes, as well as create their own with a minimum of effort.
This commit is contained in:
@@ -16,63 +16,42 @@
|
||||
|
||||
package org.springframework.transaction.annotation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aop.config.AopConfigUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportSelectorContext;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.context.annotation.AdviceModeImportSelector;
|
||||
import org.springframework.context.annotation.AutoProxyRegistrar;
|
||||
import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
|
||||
/**
|
||||
* Selects which implementation of {@link AbstractTransactionManagementConfiguration}
|
||||
* should be used based on the value of {@link EnableTransactionManagement#mode} on the
|
||||
* importing @{@link Configuration} class.
|
||||
* importing {@code @Configuration} class.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableTransactionManagement
|
||||
* @see AbstractTransactionManagementConfiguration
|
||||
* @see ProxyTransactionManagementConfiguration
|
||||
* @see org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration
|
||||
* @see TransactionManagementConfigUtils#TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
|
||||
*/
|
||||
public class TransactionManagementConfigurationSelector implements ImportSelector {
|
||||
public class TransactionManagementConfigurationSelector
|
||||
extends AdviceModeImportSelector<EnableTransactionManagement> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation selects {@link ProxyTransactionManagementConfiguration} if
|
||||
* {@link EnableTransactionManagement#mode()} equals {@code PROXY}, and otherwise selects
|
||||
* {@link org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration
|
||||
* AspectJTransactionManagementConfiguration}.
|
||||
* <p>If {@code #mode()} equals {@code PROXY}, an auto-proxy creator bean definition
|
||||
* will also be added to the enclosing {@link BeanDefinitionRegistry} and escalated
|
||||
* if necessary through the usual {@link AopConfigUtils} family of methods.
|
||||
* @return {@link ProxyTransactionManagementConfiguration} or
|
||||
* {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
|
||||
* {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
|
||||
*/
|
||||
public String[] selectImports(ImportSelectorContext context) {
|
||||
AnnotationMetadata importingClassMetadata = context.getImportingClassMetadata();
|
||||
BeanDefinitionRegistry registry = context.getBeanDefinitionRegistry();
|
||||
|
||||
Map<String, Object> enableTx =
|
||||
importingClassMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName());
|
||||
Assert.notNull(enableTx,
|
||||
"@EnableTransactionManagement is not present on importing class " +
|
||||
importingClassMetadata.getClassName());
|
||||
|
||||
switch ((AdviceMode) enableTx.get("mode")) {
|
||||
@Override
|
||||
protected String[] selectImports(AdviceMode adviceMode) {
|
||||
switch (adviceMode) {
|
||||
case PROXY:
|
||||
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
|
||||
if ((Boolean)enableTx.get("proxyTargetClass")) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||
}
|
||||
return new String[] { ProxyTransactionManagementConfiguration.class.getName() };
|
||||
return new String[] { AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName() };
|
||||
case ASPECTJ:
|
||||
return new String[] {"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
|
||||
return new String[] { TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME };
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown AdviceMode " + enableTx.get("mode"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,10 @@ public abstract class TransactionManagementConfigUtils {
|
||||
public static final String TRANSACTION_ASPECT_CLASS_NAME =
|
||||
"org.springframework.transaction.aspectj.AnnotationTransactionAspect";
|
||||
|
||||
/**
|
||||
* The name of the AspectJ transaction management @{@code Configuration} class.
|
||||
*/
|
||||
public static final String TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
|
||||
"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user