SPR-6328: Rename @ImportXml -> @ImportResource and allow for usage of non-XML BeanDefinitionReader types
This commit is contained in:
parent
81efd48352
commit
ee553f7804
|
|
@ -24,6 +24,7 @@ import java.util.Set;
|
||||||
import org.springframework.beans.factory.parsing.Location;
|
import org.springframework.beans.factory.parsing.Location;
|
||||||
import org.springframework.beans.factory.parsing.Problem;
|
import org.springframework.beans.factory.parsing.Problem;
|
||||||
import org.springframework.beans.factory.parsing.ProblemReporter;
|
import org.springframework.beans.factory.parsing.ProblemReporter;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||||
import org.springframework.core.io.DescriptiveResource;
|
import org.springframework.core.io.DescriptiveResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.type.AnnotationMetadata;
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
|
|
@ -50,7 +51,7 @@ final class ConfigurationClass {
|
||||||
|
|
||||||
private String beanName;
|
private String beanName;
|
||||||
|
|
||||||
private final Set<String> xmlFilesToImport = new LinkedHashSet<String>();
|
private final Map<String, String> importedResources = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
private final Set<ConfigurationClassMethod> methods = new LinkedHashSet<ConfigurationClassMethod>();
|
private final Set<ConfigurationClassMethod> methods = new LinkedHashSet<ConfigurationClassMethod>();
|
||||||
|
|
||||||
|
|
@ -107,12 +108,12 @@ final class ConfigurationClass {
|
||||||
return this.methods;
|
return this.methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addXmlImport(String xmlImport) {
|
public void addImportedResource(String importedResource, String readerClassName) {
|
||||||
this.xmlFilesToImport.add(xmlImport);
|
this.importedResources.put(importedResource, readerClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getXmlImports() {
|
public Map<String, String> getImportedResources() {
|
||||||
return this.xmlFilesToImport;
|
return this.importedResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package org.springframework.context.annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -36,11 +37,12 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.type.AnnotationMetadata;
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
import org.springframework.core.type.MethodMetadata;
|
import org.springframework.core.type.MethodMetadata;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,7 +97,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
loadBeanDefinitionsForModelMethod(method);
|
loadBeanDefinitionsForModelMethod(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBeanDefinitionsFromXml(configClass.getXmlImports());
|
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -212,10 +214,29 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
registry.registerBeanDefinition(beanName, beanDefToRegister);
|
registry.registerBeanDefinition(beanName, beanDefToRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadBeanDefinitionsFromXml(Set<String> xmlImports) {
|
private void loadBeanDefinitionsFromImportedResources(Map<String, String> importedResources) {
|
||||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.registry);
|
|
||||||
// TODO SPR-6310: qualify relatively pathed locations as done in AbstractContextLoader.modifyLocations
|
HashMap<String, BeanDefinitionReader> readerInstanceCache = new HashMap<String, BeanDefinitionReader>();
|
||||||
reader.loadBeanDefinitions(xmlImports.toArray(new String[]{}));
|
|
||||||
|
for (String resource : importedResources.keySet()) {
|
||||||
|
String readerClassName = importedResources.get(resource);
|
||||||
|
|
||||||
|
if (!readerInstanceCache.containsKey(readerClassName)) {
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<? extends BeanDefinitionReader> readerClass =
|
||||||
|
(Class<? extends BeanDefinitionReader>) ClassUtils.forName(readerClassName, ClassUtils.getDefaultClassLoader());
|
||||||
|
BeanDefinitionReader readerInstance = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
|
||||||
|
readerInstanceCache.put(readerClassName, readerInstance);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ReflectionUtils.handleReflectionException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanDefinitionReader reader = readerInstanceCache.get(readerClassName);
|
||||||
|
// TODO SPR-6310: qualify relatively pathed locations as done in AbstractContextLoader.modifyLocations
|
||||||
|
reader.loadBeanDefinitions(importedResources.keySet().toArray(new String[]{}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,14 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.parsing.Location;
|
import org.springframework.beans.factory.parsing.Location;
|
||||||
import org.springframework.beans.factory.parsing.Problem;
|
import org.springframework.beans.factory.parsing.Problem;
|
||||||
import org.springframework.beans.factory.parsing.ProblemReporter;
|
import org.springframework.beans.factory.parsing.ProblemReporter;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.type.AnnotationMetadata;
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
import org.springframework.core.type.MethodMetadata;
|
import org.springframework.core.type.MethodMetadata;
|
||||||
import org.springframework.core.type.StandardAnnotationMetadata;
|
import org.springframework.core.type.StandardAnnotationMetadata;
|
||||||
import org.springframework.core.type.classreading.MetadataReader;
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a {@link Configuration} class definition, populating a model (collection) of
|
* Parses a {@link Configuration} class definition, populating a model (collection) of
|
||||||
|
|
@ -128,9 +130,10 @@ class ConfigurationClassParser {
|
||||||
if (metadata.isAnnotated(Import.class.getName())) {
|
if (metadata.isAnnotated(Import.class.getName())) {
|
||||||
processImport(configClass, (String[]) metadata.getAnnotationAttributes(Import.class.getName()).get("value"));
|
processImport(configClass, (String[]) metadata.getAnnotationAttributes(Import.class.getName()).get("value"));
|
||||||
}
|
}
|
||||||
if (metadata.isAnnotated(ImportXml.class.getName())) {
|
if (metadata.isAnnotated(ImportResource.class.getName())) {
|
||||||
for (String xmlImport : (String[]) metadata.getAnnotationAttributes(ImportXml.class.getName()).get("value")) {
|
String readerClassName = (String) metadata.getAnnotationAttributes(ImportResource.class.getName()).get("reader");
|
||||||
configClass.addXmlImport(xmlImport);
|
for (String importedResource : (String[]) metadata.getAnnotationAttributes(ImportResource.class.getName()).get("value")) {
|
||||||
|
configClass.addImportedResource(importedResource, readerClassName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Set<MethodMetadata> methods = metadata.getAnnotatedMethods(Bean.class.getName());
|
Set<MethodMetadata> methods = metadata.getAnnotatedMethods(Bean.class.getName());
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,16 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||||
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
public @interface ImportResource {
|
||||||
public @interface ImportXml {
|
|
||||||
|
|
||||||
String[] value();
|
String[] value();
|
||||||
|
|
||||||
|
Class<? extends BeanDefinitionReader> reader() default XmlBeanDefinitionReader.class;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
propertiesDeclaredBean.(class)=test.beans.TestBean
|
||||||
|
|
@ -26,20 +26,22 @@ import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
|
||||||
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
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.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.ImportXml;
|
import org.springframework.context.annotation.ImportResource;
|
||||||
|
|
||||||
import test.beans.TestBean;
|
import test.beans.TestBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link ImportXml} support.
|
* Integration tests for {@link ImportResource} support.
|
||||||
*
|
*
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
*/
|
*/
|
||||||
public class ImportXmlTests {
|
public class ImportResourceTests {
|
||||||
@Test
|
@Test
|
||||||
public void testImportXml() {
|
public void testImportXml() {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlConfig.class);
|
||||||
|
|
@ -48,7 +50,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
@ImportResource("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
||||||
static class ImportXmlConfig {
|
static class ImportXmlConfig {
|
||||||
public @Bean TestBean javaDeclaredBean() {
|
public @Bean TestBean javaDeclaredBean() {
|
||||||
return new TestBean("java.declared");
|
return new TestBean("java.declared");
|
||||||
|
|
@ -64,7 +66,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml("ImportXmlConfig-context.xml")
|
@ImportResource("ImportXmlConfig-context.xml")
|
||||||
static class ImportXmlWithRelativePathConfig {
|
static class ImportXmlWithRelativePathConfig {
|
||||||
public @Bean TestBean javaDeclaredBean() {
|
public @Bean TestBean javaDeclaredBean() {
|
||||||
return new TestBean("java.declared");
|
return new TestBean("java.declared");
|
||||||
|
|
@ -97,7 +99,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
@ImportResource("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
||||||
static class BaseConfig {
|
static class BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +108,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml("classpath:org/springframework/context/annotation/configuration/SecondLevelSubConfig-context.xml")
|
@ImportResource("classpath:org/springframework/context/annotation/configuration/SecondLevelSubConfig-context.xml")
|
||||||
static class SecondLevelSubConfig extends BaseConfig {
|
static class SecondLevelSubConfig extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +120,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml("classpath:org/springframework/context/annotation/configuration/ImportXmlWithAopNamespace-context.xml")
|
@ImportResource("classpath:org/springframework/context/annotation/configuration/ImportXmlWithAopNamespace-context.xml")
|
||||||
static class ImportXmlWithAopNamespaceConfig {
|
static class ImportXmlWithAopNamespaceConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +138,7 @@ public class ImportXmlTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportXml(value="classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
@ImportResource(value="classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
||||||
static class ImportXmlAutowiredConfig {
|
static class ImportXmlAutowiredConfig {
|
||||||
@Autowired TestBean xmlDeclaredBean;
|
@Autowired TestBean xmlDeclaredBean;
|
||||||
|
|
||||||
|
|
@ -144,5 +146,30 @@ public class ImportXmlTests {
|
||||||
return xmlDeclaredBean.getName();
|
return xmlDeclaredBean.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testImportNonXmlResource() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportNonXmlResourceConfig.class);
|
||||||
|
assertTrue(ctx.containsBean("propertiesDeclaredBean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ImportResource(value="classpath:org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig-context.properties",
|
||||||
|
reader=PropertiesBeanDefinitionReader.class)
|
||||||
|
static class ImportNonXmlResourceConfig {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore // TODO: SPR-6327
|
||||||
|
@Test
|
||||||
|
public void testImportDifferentResourceTypes() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SubResourceConfig.class);
|
||||||
|
assertTrue(ctx.containsBean("propertiesDeclaredBean"));
|
||||||
|
assertTrue(ctx.containsBean("xmlDeclaredBean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ImportResource(value="classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml",
|
||||||
|
reader=XmlBeanDefinitionReader.class)
|
||||||
|
static class SubResourceConfig extends ImportNonXmlResourceConfig {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<bean id="proxiedXmlBean" class="test.beans.TestBean"/>
|
<bean id="proxiedXmlBean" class="test.beans.TestBean"/>
|
||||||
|
|
||||||
<bean id="anAspect" class="org.springframework.context.annotation.configuration.ImportXmlTests$AnAspect"/>
|
<bean id="anAspect" class="org.springframework.context.annotation.configuration.ImportResourceTests$AnAspect"/>
|
||||||
|
|
||||||
<aop:aspectj-autoproxy>
|
<aop:aspectj-autoproxy>
|
||||||
<aop:include name="anAspect"/>
|
<aop:include name="anAspect"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue