Move ImportSelector.Context to a top-level class

Issue: SPR-8411, SPR-8494
This commit is contained in:
Chris Beams 2011-07-13 23:28:53 +00:00
parent 0c2a6395e7
commit c5463a2e52
6 changed files with 52 additions and 48 deletions

View File

@ -248,7 +248,7 @@ class ConfigurationClassParser {
// the candidate class is an ImportSelector -> delegate to it to determine imports // the candidate class is an ImportSelector -> delegate to it to determine imports
try { try {
ImportSelector selector = BeanUtils.instantiateClass(Class.forName(candidate), ImportSelector.class); ImportSelector selector = BeanUtils.instantiateClass(Class.forName(candidate), ImportSelector.class);
ImportSelector.Context context = new ImportSelector.Context(importingClassMetadata, this.registry); ImportSelectorContext context = new ImportSelectorContext(importingClassMetadata, this.registry);
processImport(configClass, selector.selectImports(context), false); processImport(configClass, selector.selectImports(context), false);
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2011 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.
@ -23,26 +23,26 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* Indicates one or more @{@link @Configuration} classes to import. * Indicates one or more @{@link Configuration} classes to import.
* *
* <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML. * <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
* Only supported for actual {@code @Configuration}-annotated classes and implementations * Only supported for actual {@code @Configuration}-annotated classes and implementations
* of the {@link ImportSelector} interface. * of the {@link ImportSelector} interface.
* *
* <p>{@link Bean @Bean} definitions declared in imported {@code @Configuration} classes * <p>@{@link Bean} definitions declared in imported {@code @Configuration} classes
* should be accessed by using {@link Autowired @Autowired} injection. Either the bean * should be accessed by using @{@link Autowired} injection. Either the bean itself can
* itself can be autowired, or the configuration class instance declaring the bean can be * be autowired, or the configuration class instance declaring the bean can be autowired.
* autowired. The latter approach allows for explicit, IDE-friendly navigation between * The latter approach allows for explicit, IDE-friendly navigation between
* {@code @Configuration} class methods. * {@code @Configuration} class methods.
* *
* <p>If XML or other non-{@code @Configuration} bean definition resources need to be * <p>If XML or other non-{@code @Configuration} bean definition resources need to be
* imported, use {@link ImportResource @ImportResource} * imported, use @{@link ImportResource}
* *
* @author Chris Beams * @author Chris Beams
* @since 3.0 * @since 3.0
* @see Configuration * @see Configuration
* @see ImportResource
* @see ImportSelector * @see ImportSelector
* @see ImportResource
*/ */
@Target({ElementType.TYPE}) @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ -50,7 +50,7 @@ import java.lang.annotation.Target;
public @interface Import { public @interface Import {
/** /**
* The {@link Configuration} class or classes to import. * The @{@link Configuration} and/or {@link ImportSelector} classes to import.
*/ */
Class<?>[] value(); Class<?>[] value();
} }

View File

@ -16,17 +16,14 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.type.AnnotationMetadata;
/** /**
* Interface to be implemented by types that determine which @{@link Configuration} * Interface to be implemented by types that determine which @{@link Configuration}
* class(es) should be imported based on a given selection criteria, usually one or more * class(es) should be imported based on a given selection criteria, usually one or more
* annotation attributes. * annotation attributes.
* *
* <p>In certain cases, an {@code ImportSelector} may register additional bean definitions * <p>In certain cases, an {@code ImportSelector} may register additional bean definitions
* through the {@link BeanDefinitionRegistry} available in the * through the {@code BeanDefinitionRegistry} available in the
* {@code Context} provided to the {@link #selectImports} method. * {@link ImportSelectorContext} provided to the {@link #selectImports} method.
* *
* @author Chris Beams * @author Chris Beams
* @since 3.1 * @since 3.1
@ -40,37 +37,9 @@ public interface ImportSelector {
* the {@code AnnotationMetadata} of the importing {@code @Configuration} class and * the {@code AnnotationMetadata} of the importing {@code @Configuration} class and
* optionally register any {@code BeanDefinition}s necessary to support the selected * optionally register any {@code BeanDefinition}s necessary to support the selected
* classes. * classes.
* @param context containing the AnnotationMetadata of the importing @{@link * @param context containing the {@code AnnotationMetadata} of the importing @{@link
* Configuration} class and the enclosing {@link BeanDefinitionRegistry}. * Configuration} class and the enclosing {@code BeanDefinitionRegistry}.
*/ */
String[] selectImports(Context context); String[] selectImports(ImportSelectorContext context);
/**
* Context object holding the {@link AnnotationMetadata} of the {@code @Configuration}
* class that imported this {@link ImportSelector} as well as the enclosing
* {@link BeanDefinitionRegistry} to allow for conditional bean definition
* registration when necessary.
*
* @author Chris Beams
* @since 3.1
*/
static class Context {
private final AnnotationMetadata importingClassMetadata;
private final BeanDefinitionRegistry registry;
public Context(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
this.importingClassMetadata = importingClassMetadata;
this.registry = registry;
}
public AnnotationMetadata getImportingClassMetadata() {
return this.importingClassMetadata;
}
public BeanDefinitionRegistry getBeanDefinitionRegistry() {
return registry;
}
}
} }

View File

@ -0,0 +1,33 @@
package org.springframework.context.annotation;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.type.AnnotationMetadata;
/**
* Context object holding the {@link AnnotationMetadata} of the @{@link Configuration}
* class that imported the current {@link ImportSelector} as well as the enclosing
* {@link BeanDefinitionRegistry} to allow for conditional bean definition
* registration when necessary.
*
* @author Chris Beams
* @since 3.1
* @see Import
* @see ImportSelector
*/
public class ImportSelectorContext {
private final AnnotationMetadata importingClassMetadata;
private final BeanDefinitionRegistry registry;
ImportSelectorContext(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
this.importingClassMetadata = importingClassMetadata;
this.registry = registry;
}
public AnnotationMetadata getImportingClassMetadata() {
return this.importingClassMetadata;
}
public BeanDefinitionRegistry getBeanDefinitionRegistry() {
return registry;
}
}

View File

@ -19,6 +19,7 @@ package org.springframework.scheduling.annotation;
import java.util.Map; import java.util.Map;
import org.springframework.context.annotation.AnnotationConfigUtils; import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ImportSelectorContext;
import org.springframework.context.annotation.ImportSelector; import org.springframework.context.annotation.ImportSelector;
import org.springframework.context.config.AdviceMode; import org.springframework.context.config.AdviceMode;
import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.AnnotationMetadata;
@ -46,7 +47,7 @@ public class AsyncConfigurationSelector implements ImportSelector {
* AspectJAsyncConfiguration}. No additional {@code BeanDefinition}s are registered * AspectJAsyncConfiguration}. No additional {@code BeanDefinition}s are registered
* in either case. * in either case.
*/ */
public String[] selectImports(ImportSelector.Context context) { public String[] selectImports(ImportSelectorContext context) {
AnnotationMetadata importingClassMetadata = context.getImportingClassMetadata(); AnnotationMetadata importingClassMetadata = context.getImportingClassMetadata();
Map<String, Object> enableAsync = Map<String, Object> enableAsync =
importingClassMetadata.getAnnotationAttributes(EnableAsync.class.getName()); importingClassMetadata.getAnnotationAttributes(EnableAsync.class.getName());

View File

@ -21,6 +21,7 @@ import java.util.Map;
import org.springframework.aop.config.AopConfigUtils; import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportSelectorContext;
import org.springframework.context.annotation.ImportSelector; import org.springframework.context.annotation.ImportSelector;
import org.springframework.context.config.AdviceMode; import org.springframework.context.config.AdviceMode;
import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.AnnotationMetadata;
@ -50,7 +51,7 @@ public class TransactionManagementConfigurationSelector implements ImportSelecto
* will also be added to the enclosing {@link BeanDefinitionRegistry} and escalated * will also be added to the enclosing {@link BeanDefinitionRegistry} and escalated
* if necessary through the usual {@link AopConfigUtils} family of methods. * if necessary through the usual {@link AopConfigUtils} family of methods.
*/ */
public String[] selectImports(ImportSelector.Context context) { public String[] selectImports(ImportSelectorContext context) {
AnnotationMetadata importingClassMetadata = context.getImportingClassMetadata(); AnnotationMetadata importingClassMetadata = context.getImportingClassMetadata();
BeanDefinitionRegistry registry = context.getBeanDefinitionRegistry(); BeanDefinitionRegistry registry = context.getBeanDefinitionRegistry();