introduced BeanDefinitionRegistryPostProcessor extension to BeanFactoryPostProcessor; @Configuration classes support definition of BeanFactoryPostProcessor beans as well (SPR-6455, SPR-6611)
This commit is contained in:
parent
2d6ea2f4fe
commit
6b2b5c4c23
|
|
@ -27,6 +27,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||||
import org.springframework.beans.factory.annotation.Autowire;
|
import org.springframework.beans.factory.annotation.Autowire;
|
||||||
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
||||||
|
|
@ -48,7 +49,6 @@ 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.CachingMetadataReaderFactory;
|
|
||||||
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -68,11 +68,11 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
class ConfigurationClassBeanDefinitionReader {
|
class ConfigurationClassBeanDefinitionReader {
|
||||||
|
|
||||||
static final String CONFIGURATION_CLASS_FULL = "full";
|
private static final String CONFIGURATION_CLASS_FULL = "full";
|
||||||
|
|
||||||
static final String CONFIGURATION_CLASS_LITE = "lite";
|
private static final String CONFIGURATION_CLASS_LITE = "lite";
|
||||||
|
|
||||||
static final String CONFIGURATION_CLASS_ATTRIBUTE =
|
private static final String CONFIGURATION_CLASS_ATTRIBUTE =
|
||||||
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
|
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(ConfigurationClassBeanDefinitionReader.class);
|
private static final Log logger = LogFactory.getLog(ConfigurationClassBeanDefinitionReader.class);
|
||||||
|
|
@ -86,7 +86,6 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
private final MetadataReaderFactory metadataReaderFactory;
|
private final MetadataReaderFactory metadataReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ConfigurationClassBeanDefinitionReader} instance that will be used
|
* Create a new {@link ConfigurationClassBeanDefinitionReader} instance that will be used
|
||||||
* to populate the given {@link BeanDefinitionRegistry}.
|
* to populate the given {@link BeanDefinitionRegistry}.
|
||||||
|
|
@ -95,6 +94,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
*/
|
*/
|
||||||
public ConfigurationClassBeanDefinitionReader(BeanDefinitionRegistry registry, SourceExtractor sourceExtractor,
|
public ConfigurationClassBeanDefinitionReader(BeanDefinitionRegistry registry, SourceExtractor sourceExtractor,
|
||||||
ProblemReporter problemReporter, MetadataReaderFactory metadataReaderFactory) {
|
ProblemReporter problemReporter, MetadataReaderFactory metadataReaderFactory) {
|
||||||
|
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.sourceExtractor = sourceExtractor;
|
this.sourceExtractor = sourceExtractor;
|
||||||
this.problemReporter = problemReporter;
|
this.problemReporter = problemReporter;
|
||||||
|
|
@ -145,13 +145,15 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Registered bean definition for imported @Configuration class %s", configBeanName));
|
logger.debug(String.format("Registered bean definition for imported @Configuration class %s", configBeanName));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
try {
|
try {
|
||||||
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
|
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
|
||||||
AnnotationMetadata metadata = reader.getAnnotationMetadata();
|
AnnotationMetadata metadata = reader.getAnnotationMetadata();
|
||||||
this.problemReporter.error(
|
this.problemReporter.error(
|
||||||
new InvalidConfigurationImportProblem(className, reader.getResource(), metadata));
|
new InvalidConfigurationImportProblem(className, reader.getResource(), metadata));
|
||||||
} catch (IOException ex) {
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
throw new IllegalStateException("Could not create MetadataReader for class " + className);
|
throw new IllegalStateException("Could not create MetadataReader for class " + className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +183,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
this.registry.registerAlias(beanName, alias);
|
this.registry.registerAlias(beanName, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
// has this already been overriden (i.e.: via XML)?
|
// has this already been overridden (e.g. via XML)?
|
||||||
if (this.registry.containsBeanDefinition(beanName)) {
|
if (this.registry.containsBeanDefinition(beanName)) {
|
||||||
BeanDefinition existingBeanDef = registry.getBeanDefinition(beanName);
|
BeanDefinition existingBeanDef = registry.getBeanDefinition(beanName);
|
||||||
// is the existing bean definition one that was created from a configuration class?
|
// is the existing bean definition one that was created from a configuration class?
|
||||||
|
|
@ -277,6 +279,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the given bean definition is a candidate for a configuration class,
|
* Check whether the given bean definition is a candidate for a configuration class,
|
||||||
* and mark it accordingly.
|
* and mark it accordingly.
|
||||||
|
|
@ -284,7 +287,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
* @param metadataReaderFactory the current factory in use by the caller
|
* @param metadataReaderFactory the current factory in use by the caller
|
||||||
* @return whether the candidate qualifies as (any kind of) configuration class
|
* @return whether the candidate qualifies as (any kind of) configuration class
|
||||||
*/
|
*/
|
||||||
static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
|
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
|
||||||
AnnotationMetadata metadata = null;
|
AnnotationMetadata metadata = null;
|
||||||
|
|
||||||
// Check already loaded Class if present...
|
// Check already loaded Class if present...
|
||||||
|
|
@ -322,6 +325,14 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given bean definition indicates a full @Configuration class.
|
||||||
|
*/
|
||||||
|
public static boolean isFullConfigurationClass(BeanDefinition beanDef) {
|
||||||
|
return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RootBeanDefinition} marker subclass used to signify that a bean definition
|
* {@link RootBeanDefinition} marker subclass used to signify that a bean definition
|
||||||
* created from a configuration class as opposed to any other configuration source.
|
* created from a configuration class as opposed to any other configuration source.
|
||||||
|
|
@ -329,7 +340,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
* definition was created externally.
|
* definition was created externally.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
|
private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
|
||||||
|
|
||||||
private AnnotationMetadata annotationMetadata;
|
private AnnotationMetadata annotationMetadata;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import static org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.CONFIGURATION_CLASS_ATTRIBUTE;
|
|
||||||
import static org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.CONFIGURATION_CLASS_FULL;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
@ -40,6 +37,7 @@ import org.springframework.beans.factory.parsing.ProblemReporter;
|
||||||
import org.springframework.beans.factory.parsing.SourceExtractor;
|
import org.springframework.beans.factory.parsing.SourceExtractor;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
|
@ -63,7 +61,7 @@ import org.springframework.util.ClassUtils;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class ConfigurationClassPostProcessor implements BeanFactoryPostProcessor, BeanClassLoaderAware {
|
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanClassLoaderAware {
|
||||||
|
|
||||||
/** Whether the CGLIB2 library is present on the classpath */
|
/** Whether the CGLIB2 library is present on the classpath */
|
||||||
private static final boolean cglibAvailable = ClassUtils.isPresent(
|
private static final boolean cglibAvailable = ClassUtils.isPresent(
|
||||||
|
|
@ -124,16 +122,18 @@ public class ConfigurationClassPostProcessor implements BeanFactoryPostProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive further bean definitions from the configuration classes in the registry.
|
||||||
|
*/
|
||||||
|
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
|
||||||
|
processConfigBeanDefinitions(registry);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the Configuration classes for servicing bean requests at runtime
|
* Prepare the Configuration classes for servicing bean requests at runtime
|
||||||
* by replacing them with CGLIB-enhanced subclasses.
|
* by replacing them with CGLIB-enhanced subclasses.
|
||||||
*/
|
*/
|
||||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||||||
if (!(beanFactory instanceof BeanDefinitionRegistry)) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"ConfigurationClassPostProcessor expects a BeanFactory that implements BeanDefinitionRegistry");
|
|
||||||
}
|
|
||||||
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
|
|
||||||
enhanceConfigurationClasses(beanFactory);
|
enhanceConfigurationClasses(beanFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,8 +174,8 @@ 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
|
||||||
ConfigurationClassBeanDefinitionReader reader =
|
ConfigurationClassBeanDefinitionReader reader = new ConfigurationClassBeanDefinitionReader(
|
||||||
new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.problemReporter, this.metadataReaderFactory);
|
registry, this.sourceExtractor, this.problemReporter, this.metadataReaderFactory);
|
||||||
reader.loadBeanDefinitions(parser.getConfigurationClasses());
|
reader.loadBeanDefinitions(parser.getConfigurationClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,7 +189,7 @@ public class ConfigurationClassPostProcessor implements BeanFactoryPostProcessor
|
||||||
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<String, AbstractBeanDefinition>();
|
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<String, AbstractBeanDefinition>();
|
||||||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||||
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
|
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
|
||||||
if (CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE))) {
|
if (ConfigurationClassBeanDefinitionReader.isFullConfigurationClass(beanDef)) {
|
||||||
if (!(beanDef instanceof AbstractBeanDefinition)) {
|
if (!(beanDef instanceof AbstractBeanDefinition)) {
|
||||||
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
|
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
|
||||||
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
|
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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.
|
||||||
|
|
@ -39,6 +39,8 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||||
import org.springframework.beans.support.ResourceEditorRegistrar;
|
import org.springframework.beans.support.ResourceEditorRegistrar;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
@ -569,6 +571,21 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||||
* <p>Must be called before singleton instantiation.
|
* <p>Must be called before singleton instantiation.
|
||||||
*/
|
*/
|
||||||
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
|
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
|
||||||
|
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
|
||||||
|
if (beanFactory instanceof BeanDefinitionRegistry) {
|
||||||
|
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
|
||||||
|
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
|
||||||
|
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
|
||||||
|
((BeanDefinitionRegistryPostProcessor) postProcessor).postProcessBeanDefinitionRegistry(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collection<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
|
||||||
|
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false).values();
|
||||||
|
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessors) {
|
||||||
|
postProcessor.postProcessBeanDefinitionRegistry(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke factory processors registered with the context instance.
|
// Invoke factory processors registered with the context instance.
|
||||||
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
|
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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,9 +26,13 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
@ -58,6 +62,7 @@ public class ConfigurationClassProcessingTests {
|
||||||
factory.registerBeanDefinition(configBeanName, new RootBeanDefinition(configClass));
|
factory.registerBeanDefinition(configBeanName, new RootBeanDefinition(configClass));
|
||||||
}
|
}
|
||||||
ConfigurationClassPostProcessor ccpp = new ConfigurationClassPostProcessor();
|
ConfigurationClassPostProcessor ccpp = new ConfigurationClassPostProcessor();
|
||||||
|
ccpp.postProcessBeanDefinitionRegistry(factory);
|
||||||
ccpp.postProcessBeanFactory(factory);
|
ccpp.postProcessBeanFactory(factory);
|
||||||
RequiredAnnotationBeanPostProcessor rapp = new RequiredAnnotationBeanPostProcessor();
|
RequiredAnnotationBeanPostProcessor rapp = new RequiredAnnotationBeanPostProcessor();
|
||||||
rapp.setBeanFactory(factory);
|
rapp.setBeanFactory(factory);
|
||||||
|
|
@ -123,6 +128,19 @@ public class ConfigurationClassProcessingTests {
|
||||||
assertNotSame(bar.getSpouse(), baz);
|
assertNotSame(bar.getSpouse(), baz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configurationWithPostProcessor() {
|
||||||
|
BeanFactory factory = new AnnotationConfigApplicationContext(ConfigWithPostProcessor.class);
|
||||||
|
|
||||||
|
TestBean foo = factory.getBean("foo", TestBean.class);
|
||||||
|
ITestBean bar = factory.getBean("bar", ITestBean.class);
|
||||||
|
ITestBean baz = factory.getBean("baz", ITestBean.class);
|
||||||
|
|
||||||
|
assertEquals("foo-processed", foo.getName());
|
||||||
|
assertEquals("bar-processed", bar.getName());
|
||||||
|
assertEquals("baz-processed", baz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class ConfigWithBeanWithCustomName {
|
static class ConfigWithBeanWithCustomName {
|
||||||
|
|
@ -152,7 +170,9 @@ public class ConfigurationClassProcessingTests {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class ConfigWithBeanWithAliases {
|
static class ConfigWithBeanWithAliases {
|
||||||
|
|
||||||
static TestBean testBean = new TestBean();
|
static TestBean testBean = new TestBean();
|
||||||
|
|
||||||
@Bean(name={"name1", "alias1", "alias2", "alias3"})
|
@Bean(name={"name1", "alias1", "alias2", "alias3"})
|
||||||
public TestBean methodName() {
|
public TestBean methodName() {
|
||||||
return testBean;
|
return testBean;
|
||||||
|
|
@ -177,7 +197,40 @@ public class ConfigurationClassProcessingTests {
|
||||||
|
|
||||||
@Bean @Scope("prototype")
|
@Bean @Scope("prototype")
|
||||||
public TestBean baz() {
|
public TestBean baz() {
|
||||||
return new TestBean("bar");
|
return new TestBean("baz");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class ConfigWithPostProcessor extends ConfigWithPrototypeBean {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public BeanPostProcessor beanPostProcessor() {
|
||||||
|
return new BeanPostProcessor() {
|
||||||
|
String nameSuffix;
|
||||||
|
public void setNameSuffix(String nameSuffix) {
|
||||||
|
this.nameSuffix = nameSuffix;
|
||||||
|
}
|
||||||
|
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||||
|
if (bean instanceof ITestBean) {
|
||||||
|
((ITestBean) bean).setName(((ITestBean) bean).getName() + nameSuffix);
|
||||||
|
}
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public BeanFactoryPostProcessor beanFactoryPostProcessor() {
|
||||||
|
return new BeanFactoryPostProcessor() {
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||||||
|
BeanDefinition bd = beanFactory.getBeanDefinition("beanPostProcessor");
|
||||||
|
bd.getPropertyValues().addPropertyValue("nameSuffix", "-processed");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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.
|
||||||
|
|
@ -16,16 +16,17 @@
|
||||||
|
|
||||||
package org.springframework.context.annotation.configuration;
|
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.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Before;
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import test.beans.TestBean;
|
||||||
|
|
||||||
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.annotation.Value;
|
||||||
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
|
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
@ -34,12 +35,11 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.ImportResource;
|
import org.springframework.context.annotation.ImportResource;
|
||||||
|
|
||||||
import test.beans.TestBean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link ImportResource} support.
|
* Integration tests for {@link ImportResource} support.
|
||||||
*
|
*
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ImportResourceTests {
|
public class ImportResourceTests {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -47,13 +47,17 @@ public class ImportResourceTests {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlConfig.class);
|
||||||
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
||||||
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
||||||
|
TestBean tb = ctx.getBean("javaDeclaredBean", TestBean.class);
|
||||||
|
assertEquals("myName", tb.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportResource("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 {
|
||||||
|
@Value("${name}")
|
||||||
|
private String name;
|
||||||
public @Bean TestBean javaDeclaredBean() {
|
public @Bean TestBean javaDeclaredBean() {
|
||||||
return new TestBean("java.declared");
|
return new TestBean(this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,6 +67,8 @@ public class ImportResourceTests {
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlWithRelativePathConfig.class);
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlWithRelativePathConfig.class);
|
||||||
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
assertTrue("did not contain java-declared bean", ctx.containsBean("javaDeclaredBean"));
|
||||||
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
assertTrue("did not contain xml-declared bean", ctx.containsBean("xmlDeclaredBean"));
|
||||||
|
TestBean tb = ctx.getBean("javaDeclaredBean", TestBean.class);
|
||||||
|
assertEquals("myName", tb.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,12 @@
|
||||||
<constructor-arg value="xml.declared"/>
|
<constructor-arg value="xml.declared"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||||
|
<property name="properties">
|
||||||
|
<map>
|
||||||
|
<entry key="name" value="myName"/>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue