mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-05-03 04:19:47 +01:00
SPR-6158: Initial implementation and tests for @ImportXml
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2281 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
@@ -10,8 +10,14 @@
|
|||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
|
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beansProjectDescription>
|
||||||
|
<version>1</version>
|
||||||
|
<pluginVersion><![CDATA[2.2.7.200910141010-RELEASE]]></pluginVersion>
|
||||||
|
<configSuffixes>
|
||||||
|
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||||
|
</configSuffixes>
|
||||||
|
<enableImports><![CDATA[false]]></enableImports>
|
||||||
|
<configs>
|
||||||
|
<config>src/test/java/org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml</config>
|
||||||
|
</configs>
|
||||||
|
<configSets>
|
||||||
|
</configSets>
|
||||||
|
</beansProjectDescription>
|
||||||
+13
-2
@@ -50,6 +50,8 @@ final class ConfigurationClass {
|
|||||||
|
|
||||||
private String beanName;
|
private String beanName;
|
||||||
|
|
||||||
|
private final Set<String> xmlFilesToImport = new LinkedHashSet<String>();
|
||||||
|
|
||||||
private final Set<ConfigurationClassMethod> methods = new LinkedHashSet<ConfigurationClassMethod>();
|
private final Set<ConfigurationClassMethod> methods = new LinkedHashSet<ConfigurationClassMethod>();
|
||||||
|
|
||||||
private final Map<String, Integer> overloadedMethodMap = new LinkedHashMap<String, Integer>();
|
private final Map<String, Integer> overloadedMethodMap = new LinkedHashMap<String, Integer>();
|
||||||
@@ -61,7 +63,7 @@ final class ConfigurationClass {
|
|||||||
this.beanName = beanName;
|
this.beanName = beanName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationClass(Class clazz, String beanName) {
|
public ConfigurationClass(Class<?> clazz, String beanName) {
|
||||||
this.metadata = new StandardAnnotationMetadata(clazz);
|
this.metadata = new StandardAnnotationMetadata(clazz);
|
||||||
this.resource = new DescriptiveResource(clazz.toString());
|
this.resource = new DescriptiveResource(clazz.toString());
|
||||||
this.beanName = beanName;
|
this.beanName = beanName;
|
||||||
@@ -101,10 +103,19 @@ final class ConfigurationClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<ConfigurationClassMethod> getConfigurationMethods() {
|
public Set<ConfigurationClassMethod> getMethods() {
|
||||||
return this.methods;
|
return this.methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addXmlImport(String xmlImport) {
|
||||||
|
this.xmlFilesToImport.add(xmlImport);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getXmlImports() {
|
||||||
|
return this.xmlFilesToImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void validate(ProblemReporter problemReporter) {
|
public void validate(ProblemReporter problemReporter) {
|
||||||
// No overloading of factory methods allowed
|
// No overloading of factory methods allowed
|
||||||
for (Map.Entry<String, Integer> entry : this.overloadedMethodMap.entrySet()) {
|
for (Map.Entry<String, Integer> entry : this.overloadedMethodMap.entrySet()) {
|
||||||
|
|||||||
+10
-1
@@ -37,7 +37,9 @@ 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.DefaultResourceLoader;
|
||||||
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;
|
||||||
@@ -90,9 +92,11 @@ class ConfigurationClassBeanDefinitionReader {
|
|||||||
*/
|
*/
|
||||||
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass) {
|
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass) {
|
||||||
doLoadBeanDefinitionForConfigurationClass(configClass);
|
doLoadBeanDefinitionForConfigurationClass(configClass);
|
||||||
for (ConfigurationClassMethod method : configClass.getConfigurationMethods()) {
|
for (ConfigurationClassMethod method : configClass.getMethods()) {
|
||||||
loadBeanDefinitionsForModelMethod(method);
|
loadBeanDefinitionsForModelMethod(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadBeanDefinitionsFromXml(configClass.getXmlImports());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -209,6 +213,10 @@ class ConfigurationClassBeanDefinitionReader {
|
|||||||
registry.registerBeanDefinition(beanName, beanDefToRegister);
|
registry.registerBeanDefinition(beanName, beanDefToRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadBeanDefinitionsFromXml(Set<String> xmlImports) {
|
||||||
|
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.registry);
|
||||||
|
reader.loadBeanDefinitions(xmlImports.toArray(new String[]{}));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RootBeanDefinition} marker subclass used to signify that a bean definition
|
* {@link RootBeanDefinition} marker subclass used to signify that a bean definition
|
||||||
@@ -216,6 +224,7 @@ class ConfigurationClassBeanDefinitionReader {
|
|||||||
* Used in bean overriding cases where it's necessary to determine whether the bean
|
* Used in bean overriding cases where it's necessary to determine whether the bean
|
||||||
* definition was created externally.
|
* definition was created externally.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
private class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
|
private class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
|
||||||
|
|
||||||
private AnnotationMetadata annotationMetadata;
|
private AnnotationMetadata annotationMetadata;
|
||||||
|
|||||||
+27
-18
@@ -36,14 +36,18 @@ import org.springframework.core.type.classreading.MetadataReader;
|
|||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a {@link Configuration} class definition, populating a configuration model.
|
* Parses a {@link Configuration} class definition, populating a model (collection) of
|
||||||
* This ASM-based implementation avoids reflection and eager class loading in order to
|
* {@link ConfigurationClass} objects (parsing a single Configuration class may result in
|
||||||
* interoperate effectively with lazy class loading in a Spring ApplicationContext.
|
* any number of ConfigurationClass objects because one Configuration class may import
|
||||||
|
* another using the {@link Import} annotation).
|
||||||
*
|
*
|
||||||
* <p>This class helps separate the concern of parsing the structure of a Configuration
|
* <p>This class helps separate the concern of parsing the structure of a Configuration
|
||||||
* class from the concern of registering {@link BeanDefinition} objects based on the
|
* class from the concern of registering {@link BeanDefinition} objects based on the
|
||||||
* content of that model.
|
* content of that model.
|
||||||
*
|
*
|
||||||
|
* <p>This ASM-based implementation avoids reflection and eager class loading in order to
|
||||||
|
* interoperate effectively with lazy class loading in a Spring ApplicationContext.
|
||||||
|
*
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
@@ -55,19 +59,19 @@ class ConfigurationClassParser {
|
|||||||
|
|
||||||
private final ProblemReporter problemReporter;
|
private final ProblemReporter problemReporter;
|
||||||
|
|
||||||
private final Set<ConfigurationClass> model;
|
|
||||||
|
|
||||||
private final Stack<ConfigurationClass> importStack = new ImportStack();
|
private final Stack<ConfigurationClass> importStack = new ImportStack();
|
||||||
|
|
||||||
|
private final Set<ConfigurationClass> configurationClasses =
|
||||||
|
new LinkedHashSet<ConfigurationClass>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ConfigurationClassParser} instance that will be used
|
* Create a new {@link ConfigurationClassParser} instance that will be used
|
||||||
* to populate a configuration model.
|
* to populate the set of configuration classes.
|
||||||
*/
|
*/
|
||||||
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter) {
|
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter) {
|
||||||
this.metadataReaderFactory = metadataReaderFactory;
|
this.metadataReaderFactory = metadataReaderFactory;
|
||||||
this.problemReporter = problemReporter;
|
this.problemReporter = problemReporter;
|
||||||
this.model = new LinkedHashSet<ConfigurationClass>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,11 +88,11 @@ class ConfigurationClassParser {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the specified {@link Configuration @Configuration} class.
|
* Parse the specified {@link Configuration @Configuration} class.
|
||||||
* @param clazz the Clazz to parse
|
* @param clazz the Class to parse
|
||||||
* @param beanName may be null, but if populated represents the bean id
|
* @param beanName may be null, but if populated represents the bean id
|
||||||
* (assumes that this configuration class was configured via XML)
|
* (assumes that this configuration class was configured via XML)
|
||||||
*/
|
*/
|
||||||
public void parse(Class clazz, String beanName) throws IOException {
|
public void parse(Class<?> clazz, String beanName) throws IOException {
|
||||||
processConfigurationClass(new ConfigurationClass(clazz, beanName));
|
processConfigurationClass(new ConfigurationClass(clazz, beanName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +104,7 @@ class ConfigurationClassParser {
|
|||||||
String superClassName = metadata.getSuperClassName();
|
String superClassName = metadata.getSuperClassName();
|
||||||
if (superClassName != null && !Object.class.getName().equals(superClassName)) {
|
if (superClassName != null && !Object.class.getName().equals(superClassName)) {
|
||||||
if (metadata instanceof StandardAnnotationMetadata) {
|
if (metadata instanceof StandardAnnotationMetadata) {
|
||||||
Class clazz = ((StandardAnnotationMetadata) metadata).getIntrospectedClass();
|
Class<?> clazz = ((StandardAnnotationMetadata) metadata).getIntrospectedClass();
|
||||||
metadata = new StandardAnnotationMetadata(clazz.getSuperclass());
|
metadata = new StandardAnnotationMetadata(clazz.getSuperclass());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -112,25 +116,30 @@ class ConfigurationClassParser {
|
|||||||
metadata = null;
|
metadata = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.model.contains(configClass) && configClass.getBeanName() != null) {
|
if (this.configurationClasses.contains(configClass) && configClass.getBeanName() != null) {
|
||||||
// Explicit bean definition found, probably replacing an import.
|
// Explicit bean definition found, probably replacing an import.
|
||||||
// Let's remove the old one and go with the new one.
|
// Let's remove the old one and go with the new one.
|
||||||
this.model.remove(configClass);
|
this.configurationClasses.remove(configClass);
|
||||||
}
|
}
|
||||||
this.model.add(configClass);
|
this.configurationClasses.add(configClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doProcessConfigurationClass(ConfigurationClass configClass, AnnotationMetadata metadata) throws IOException {
|
protected void doProcessConfigurationClass(ConfigurationClass configClass, AnnotationMetadata metadata) throws IOException {
|
||||||
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())) {
|
||||||
|
for (String xmlImport : (String[]) metadata.getAnnotationAttributes(ImportXml.class.getName()).get("value")) {
|
||||||
|
configClass.addXmlImport(xmlImport);
|
||||||
|
}
|
||||||
|
}
|
||||||
Set<MethodMetadata> methods = metadata.getAnnotatedMethods(Bean.class.getName());
|
Set<MethodMetadata> methods = metadata.getAnnotatedMethods(Bean.class.getName());
|
||||||
for (MethodMetadata methodMetadata : methods) {
|
for (MethodMetadata methodMetadata : methods) {
|
||||||
configClass.addMethod(new ConfigurationClassMethod(methodMetadata, configClass));
|
configClass.addMethod(new ConfigurationClassMethod(methodMetadata, configClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processImport(ConfigurationClass configClass, String[] classesToImport) throws IOException {
|
private void processImport(ConfigurationClass configClass, String[] classesToImport) throws IOException {
|
||||||
if (this.importStack.contains(configClass)) {
|
if (this.importStack.contains(configClass)) {
|
||||||
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata()));
|
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata()));
|
||||||
}
|
}
|
||||||
@@ -156,17 +165,17 @@ class ConfigurationClassParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recurse through the model validating each {@link ConfigurationClass}.
|
* Validate each {@link ConfigurationClass} object.
|
||||||
* @see ConfigurationClass#validate
|
* @see ConfigurationClass#validate
|
||||||
*/
|
*/
|
||||||
public void validate() {
|
public void validate() {
|
||||||
for (ConfigurationClass configClass : this.model) {
|
for (ConfigurationClass configClass : this.configurationClasses) {
|
||||||
configClass.validate(this.problemReporter);
|
configClass.validate(this.problemReporter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<ConfigurationClass> getModel() {
|
public Set<ConfigurationClass> getConfigurationClasses() {
|
||||||
return this.model;
|
return this.configurationClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public class ConfigurationClassPostProcessor implements BeanFactoryPostProcessor
|
|||||||
parser.validate();
|
parser.validate();
|
||||||
|
|
||||||
// Read the model and create bean definitions based on its content
|
// Read the model and create bean definitions based on its content
|
||||||
new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor).loadBeanDefinitions(parser.getModel());
|
new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor).loadBeanDefinitions(parser.getConfigurationClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Documented
|
||||||
|
public @interface ImportXml {
|
||||||
|
|
||||||
|
String[] value();
|
||||||
|
|
||||||
|
Class<?> relativeTo() default void.class;
|
||||||
|
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
|
||||||
|
<bean id="xmlDeclaredBean" class="org.springframework.beans.TestBean">
|
||||||
|
<constructor-arg value="xml.declaraed"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.context.annotation.configuration;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.ImportXml;
|
||||||
|
|
||||||
|
import test.beans.TestBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link ImportXml} support.
|
||||||
|
*
|
||||||
|
* @author Chris Beams
|
||||||
|
*/
|
||||||
|
public class ImportXmlTests {
|
||||||
|
@Test
|
||||||
|
public void testImportXmlWorks() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlConfig.class);
|
||||||
|
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
||||||
|
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ImportXml("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
||||||
|
static class ImportXmlConfig {
|
||||||
|
public @Bean TestBean javaDeclaredBean() {
|
||||||
|
return new TestBean("java.declared");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testImportXmlWorksWithRelativePathing() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportsXmlWithRelativeTo.class);
|
||||||
|
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
||||||
|
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ImportXml(value="beans.xml", relativeTo=ImportXmlTests.class)
|
||||||
|
static class ImportsXmlWithRelativeTo {
|
||||||
|
public @Bean TestBean javaDeclaredBean() {
|
||||||
|
return new TestBean("java.declared");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testImportXmlWorksWithAutowired() {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AutowiredImportXml.class);
|
||||||
|
String name = ctx.getBean("xmlBeanName", String.class);
|
||||||
|
assertThat(name, equalTo("xmlBean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ImportXml(value="beans.xml", relativeTo=AutowiredImportXml.class)
|
||||||
|
static class AutowiredImportXml {
|
||||||
|
@Autowired TestBean xmlDeclaredBean;
|
||||||
|
|
||||||
|
public @Bean String xmlBeanName() {
|
||||||
|
return xmlDeclaredBean.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user