M1 cut of environment, profiles and property work (SPR-7508)
Decomposed Environment interface into PropertySources, PropertyResolver
objects
Environment interface and implementations are still present, but
simpler.
PropertySources container aggregates PropertySource objects;
PropertyResolver provides search, conversion, placeholder
replacement. Single implementation for now is
PropertySourcesPlaceholderResolver
Renamed EnvironmentAwarePropertyPlaceholderConfigurer to
PropertySourcesPlaceholderConfigurer
<context:property-placeholder/> now registers PSPC by default, else
PPC if systemPropertiesMode* settings are involved
Refined configuration and behavior of default profiles
See Environment interface Javadoc for details
Added Portlet implementations of relevant interfaces:
* DefaultPortletEnvironment
* PortletConfigPropertySource, PortletContextPropertySource
* Integrated each appropriately throughout Portlet app contexts
Added protected 'createEnvironment()' method to AbstractApplicationContext
Subclasses can override at will to supply a custom Environment
implementation. In practice throughout the framework, this is how
Web- and Portlet-related ApplicationContexts override use of the
DefaultEnvironment and swap in DefaultWebEnvironment or
DefaultPortletEnvironment as appropriate.
Introduced "stub-and-replace" behavior for Servlet- and Portlet-based
PropertySource implementations
Allows for early registration and ordering of the stub, then
replacement with actual backing object at refresh() time.
Added AbstractApplicationContext.initPropertySources() method to
support stub-and-replace behavior. Called from within existing
prepareRefresh() method so as to avoid impact with
ApplicationContext implementations that copy and modify AAC's
refresh() method (e.g.: Spring DM).
Added methods to WebApplicationContextUtils and
PortletApplicationContextUtils to support stub-and-replace behavior
Added comprehensive Javadoc for all new or modified types and members
Added XSD documentation for all new or modified elements and attributes
Including nested <beans>, <beans profile="..."/>, and changes for
certain attributes type from xsd:IDREF to xsd:string
Improved fix for detecting non-file based Resources in
PropertiesLoaderSupport (SPR-7547, SPR-7552)
Technically unrelated to environment work, but grouped in with
this changeset for convenience.
Deprecated (removed) context:property-placeholder
'system-properties-mode' attribute from spring-context-3.1.xsd
Functionality is preserved for those using schemas up to and including
spring-context-3.0. For 3.1, system-properties-mode is no longer
supported as it conflicts with the idea of managing a set of property
sources within the context's Environment object. See Javadoc in
PropertyPlaceholderConfigurer, AbstractPropertyPlaceholderConfigurer
and PropertySourcesPlaceholderConfigurer for details.
Introduced CollectionUtils.toArray(Enumeration<E>, A[])
Work items remaining for 3.1 M2:
Consider repackaging PropertySource* types; eliminate internal use
of SystemPropertyUtils and deprecate
Further work on composition of Environment interface; consider
repurposing existing PlaceholderResolver interface to obviate need
for resolve[Required]Placeholder() methods currently in Environment.
Ensure configurability of placeholder prefix, suffix, and value
separator when working against an AbstractPropertyResolver
Add JNDI-based Environment / PropertySource implementatinos
Consider support for @Profile at the @Bean level
Provide consistent logging for the entire property resolution
lifecycle; consider issuing all such messages against a dedicated
logger with a single category.
Add reference documentation to cover the featureset.
This commit is contained in:
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -96,12 +96,13 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
void setParent(ApplicationContext parent);
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
* Return the Environment for this application context in configurable form.
|
||||
*/
|
||||
ConfigurableEnvironment getEnvironment();
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
* Set the {@code Environment} for this application context.
|
||||
* @param environment the new environment
|
||||
*/
|
||||
void setEnvironment(ConfigurableEnvironment environment);
|
||||
|
||||
|
||||
@@ -19,12 +19,17 @@ package org.springframework.context;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* TODO SPR-7515: document
|
||||
* Interface to be implemented by any bean that wishes to be notified
|
||||
* of the {@link Environment} that it runs in.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface EnvironmentAware {
|
||||
|
||||
/**
|
||||
* Set the {@code Environment} that this object runs in.
|
||||
*/
|
||||
void setEnvironment(Environment environment);
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,9 +50,9 @@ public class AnnotatedBeanDefinitionReader {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AnnotatedBeanDefinitionReader for the given bean factory.
|
||||
* @param registry the BeanFactory to load bean definitions into,
|
||||
* in the form of a BeanDefinitionRegistry
|
||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given bean factory.
|
||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||
* in the form of a {@code BeanDefinitionRegistry}
|
||||
*/
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||
this.registry = registry;
|
||||
@@ -68,8 +68,10 @@ public class AnnotatedBeanDefinitionReader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Environment to use when registering classes.
|
||||
* Set the Environment to use when evaluating whether
|
||||
* {@link Profile @Profile}-annotated component classes should be registered.
|
||||
* <p>The default is a {@link DefaultEnvironment}.
|
||||
* @see #registerBean(Class, String, Class...)
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
@@ -80,7 +82,8 @@ public class AnnotatedBeanDefinitionReader {
|
||||
* <p>The default is a {@link AnnotationBeanNameGenerator}.
|
||||
*/
|
||||
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||
this.beanNameGenerator = (beanNameGenerator != null ?
|
||||
beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +91,8 @@ public class AnnotatedBeanDefinitionReader {
|
||||
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
||||
*/
|
||||
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
||||
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
|
||||
this.scopeMetadataResolver = (scopeMetadataResolver != null ?
|
||||
scopeMetadataResolver : new AnnotationScopeMetadataResolver());
|
||||
}
|
||||
|
||||
|
||||
@@ -110,10 +114,8 @@ public class AnnotatedBeanDefinitionReader {
|
||||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
||||
AnnotationMetadata metadata = abd.getMetadata();
|
||||
|
||||
if (metadata.hasAnnotation(Profile.class.getName())) {
|
||||
String[] specifiedProfiles =
|
||||
(String[])metadata.getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME);
|
||||
if (!this.environment.acceptsProfiles(specifiedProfiles)) {
|
||||
if (Profile.Helper.isProfileAnnotationPresent(metadata)) {
|
||||
if (!this.environment.acceptsProfiles(Profile.Helper.getCandidateProfiles(metadata))) {
|
||||
// TODO SPR-7508: log that this bean is being rejected on profile mismatch
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,17 +16,15 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* Standalone application context, accepting annotated classes as input - in particular
|
||||
* {@link org.springframework.context.annotation.Configuration @Configuration}-annotated
|
||||
* classes, but also plain {@link org.springframework.stereotype.Component @Components}
|
||||
* and JSR-330 compliant classes using {@literal javax.inject} annotations. Allows for
|
||||
* and JSR-330 compliant classes using {@code javax.inject} annotations. Allows for
|
||||
* registering classes one by one ({@link #register}) as well as for classpath scanning
|
||||
* ({@link #scan}).
|
||||
*
|
||||
@@ -49,15 +47,13 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
|
||||
|
||||
private final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this);
|
||||
|
||||
{ // TODO: rework this, it's a bit confusing
|
||||
this.setEnvironment(this.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AnnotationConfigApplicationContext that needs to be populated
|
||||
* through {@link #register} calls and then manually {@link #refresh refreshed}.
|
||||
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
|
||||
*/
|
||||
public AnnotationConfigApplicationContext() {
|
||||
this.delegateEnvironment(super.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +63,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
|
||||
* e.g. {@link Configuration @Configuration} classes
|
||||
*/
|
||||
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
|
||||
this();
|
||||
register(annotatedClasses);
|
||||
refresh();
|
||||
}
|
||||
@@ -77,16 +74,24 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
|
||||
* @param basePackages the packages to check for annotated classes
|
||||
*/
|
||||
public AnnotationConfigApplicationContext(String... basePackages) {
|
||||
this();
|
||||
scan(basePackages);
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
* {@inheritDoc}
|
||||
* <p>Delegates given environment to underlying {@link AnnotatedBeanDefinitionReader}
|
||||
* and {@link ClassPathBeanDefinitionScanner} members.
|
||||
*/
|
||||
@Override
|
||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||
super.setEnvironment(environment);
|
||||
delegateEnvironment(environment);
|
||||
}
|
||||
|
||||
private void delegateEnvironment(ConfigurableEnvironment environment) {
|
||||
this.reader.setEnvironment(environment);
|
||||
this.scanner.setEnvironment(environment);
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ import org.springframework.beans.factory.annotation.Autowire;
|
||||
/**
|
||||
* Indicates that a method produces a bean to be managed by the Spring container. The
|
||||
* names and semantics of the attributes to this annotation are intentionally similar
|
||||
* to those of the {@literal <bean/>} element in the Spring XML schema.
|
||||
* to those of the {@code <bean/>} element in the Spring XML schema.
|
||||
*
|
||||
* <p>Note that the <code>@Bean</code> annotation does not provide attributes for scope,
|
||||
* primary or lazy. Rather, it should be used in conjunction with {@link Scope @Scope},
|
||||
* {@link Primary @Primary}, and {@link Lazy @Lazy} annotations to achieve
|
||||
* <p>Note that the {@code @Bean} annotation does not provide attributes for scope,
|
||||
* primary or lazy. Rather, it should be used in conjunction with {@link Scope @Scope},
|
||||
* {@link Primary @Primary}, and {@link Lazy @Lazy} annotations to achieve
|
||||
* those semantics. The same annotations can also be used at the type level, e.g. for
|
||||
* component scanning.
|
||||
*
|
||||
@@ -96,7 +96,7 @@ public @interface Bean {
|
||||
|
||||
/**
|
||||
* The optional name of a method to call on the bean instance upon closing the
|
||||
* application context, for example a {@literal close()} method on a {@literal DataSource}.
|
||||
* application context, for example a {@code close()} method on a {@code DataSource}.
|
||||
* The method must have no arguments but may throw any exception.
|
||||
* <p>Note: Only invoked on beans whose lifecycle is under the full control of the
|
||||
* factory, which is always the case for singletons but not guaranteed
|
||||
|
||||
@@ -116,15 +116,15 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
* Set the Environment to use when resolving placeholders and evaluating
|
||||
* {@link Profile @Profile}-annotated component classes.
|
||||
* <p>The default is a {@link DefaultEnvironment}
|
||||
* @param environment the Environment to use
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
*/
|
||||
public Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
|
||||
* @return the pattern specification to be used for package searching
|
||||
*/
|
||||
protected String resolveBasePackage(String basePackage) {
|
||||
return ClassUtils.convertClassNameToResourcePath(environment.resolveRequiredPlaceholders(basePackage));
|
||||
return ClassUtils.convertClassNameToResourcePath(environment.getPropertyResolver().resolveRequiredPlaceholders(basePackage));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,12 +298,11 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
|
||||
for (TypeFilter tf : this.includeFilters) {
|
||||
if (tf.match(metadataReader, this.metadataReaderFactory)) {
|
||||
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
|
||||
if (!metadata.hasAnnotation(Profile.class.getName())) {
|
||||
if (!Profile.Helper.isProfileAnnotationPresent(metadata)) {
|
||||
return true;
|
||||
}
|
||||
String[] specifiedProfiles =
|
||||
(String[])metadata.getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME);
|
||||
return this.environment.acceptsProfiles(specifiedProfiles);
|
||||
// TODO SPR-7508: log that this bean is being rejected on profile mismatch
|
||||
return this.environment.acceptsProfiles(Profile.Helper.getCandidateProfiles(metadata));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
/**
|
||||
* Configures component scanning directives for use with {@link Configuration}
|
||||
* classes. Provides support parallel with Spring XML's
|
||||
* <context:component-scan> element.
|
||||
* {@code <context:component-scan>} element.
|
||||
*
|
||||
* TODO SPR-7508: complete documentation.
|
||||
*
|
||||
|
||||
@@ -101,16 +101,14 @@ class ConfigurationClassParser {
|
||||
}
|
||||
|
||||
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
|
||||
if (this.environment != null && configClass.getMetadata().hasAnnotation(Profile.class.getName())) {
|
||||
String[] specifiedProfiles =
|
||||
(String[])configClass.getMetadata().getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME);
|
||||
if (!this.environment.acceptsProfiles(specifiedProfiles)) {
|
||||
AnnotationMetadata metadata = configClass.getMetadata();
|
||||
if (this.environment != null && Profile.Helper.isProfileAnnotationPresent(metadata)) {
|
||||
if (!this.environment.acceptsProfiles(Profile.Helper.getCandidateProfiles(metadata))) {
|
||||
// TODO SPR-7508: log that this bean is being rejected on profile mismatch
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AnnotationMetadata metadata = configClass.getMetadata();
|
||||
while (metadata != null) {
|
||||
doProcessConfigurationClass(configClass, metadata);
|
||||
String superClassName = metadata.getSuperClassName();
|
||||
|
||||
@@ -49,8 +49,8 @@ import org.springframework.util.ClassUtils;
|
||||
* {@link BeanFactoryPostProcessor} used for bootstrapping processing of
|
||||
* {@link Configuration @Configuration} classes.
|
||||
*
|
||||
* <p>Registered by default when using {@literal <context:annotation-config/>} or
|
||||
* {@literal <context:component-scan/>}. Otherwise, may be declared manually as
|
||||
* <p>Registered by default when using {@code <context:annotation-config/>} or
|
||||
* {@code <context:component-scan/>}. Otherwise, may be declared manually as
|
||||
* with any other BeanFactoryPostProcessor.
|
||||
*
|
||||
* <p>This post processor is {@link Ordered#HIGHEST_PRECEDENCE} as it is important
|
||||
@@ -100,7 +100,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
/**
|
||||
* Set the {@link ProblemReporter} to use.
|
||||
* <p>Used to register any problems detected with {@link Configuration} or {@link Bean}
|
||||
* declarations. For instance, an @Bean method marked as {@literal final} is illegal
|
||||
* declarations. For instance, an @Bean method marked as {@code final} is illegal
|
||||
* and would be reported as a problem. Defaults to {@link FailFastProblemReporter}.
|
||||
*/
|
||||
public void setProblemReporter(ProblemReporter problemReporter) {
|
||||
@@ -110,7 +110,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
/**
|
||||
* Set the {@link MetadataReaderFactory} to use.
|
||||
* <p>Default is a {@link CachingMetadataReaderFactory} for the specified
|
||||
* {@link #setBeanClassLoader bean class loader}.
|
||||
* {@linkplain #setBeanClassLoader bean class loader}.
|
||||
*/
|
||||
public void setMetadataReaderFactory(MetadataReaderFactory metadataReaderFactory) {
|
||||
Assert.notNull(metadataReaderFactory, "MetadataReaderFactory must not be null");
|
||||
|
||||
@@ -38,7 +38,7 @@ import java.lang.annotation.Documented;
|
||||
* <p>Using {@link DependsOn} at the class level has no effect unless component-scanning
|
||||
* is being used. If a {@link DependsOn}-annotated class is declared via XML,
|
||||
* {@link DependsOn} annotation metadata is ignored, and
|
||||
* {@literal <bean depends-on="..."/>} is respected instead.
|
||||
* {@code <bean depends-on="..."/>} is respected instead.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
|
||||
@@ -23,18 +23,18 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates one or more {@link Configuration} classes to import.
|
||||
* Indicates one or more {@link Configuration @Configuration} classes to import.
|
||||
*
|
||||
* <p>Provides functionality equivalent to the {@literal <import/>} element in Spring XML.
|
||||
* Only supported for actual {@literal @Configuration}-annotated classes.
|
||||
* <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
|
||||
* Only supported for actual {@code @Configuration}-annotated classes.
|
||||
*
|
||||
* <p>{@literal @Bean} definitions declared in imported {@literal @Configuration} classes
|
||||
* <p>{@code @Bean} definitions declared in imported {@code @Configuration} classes
|
||||
* should be accessed by using {@link Autowired @Autowired} injection. Either the bean
|
||||
* itself can be autowired, or the configuration class instance declaring the bean can be
|
||||
* autowired. The latter approach allows for explicit, IDE-friendly navigation between
|
||||
* {@literal @Configuration} class methods.
|
||||
* {@code @Configuration} class methods.
|
||||
*
|
||||
* <p>If XML or other non-{@literal @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}
|
||||
*
|
||||
* @author Chris Beams
|
||||
|
||||
@@ -30,14 +30,14 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
* Indicates one or more resources containing bean definitions to import.
|
||||
*
|
||||
* <p>Like {@link Import @Import}, this annotation provides functionality similar to the
|
||||
* {@literal <import/>} element in Spring XML. It is typically used when
|
||||
* {@code <import/>} element in Spring XML. It is typically used when
|
||||
* designing {@link Configuration @Configuration} classes to be bootstrapped by
|
||||
* {@link AnnotationConfigApplicationContext}, but where some XML functionality such as
|
||||
* namespaces is still necessary.
|
||||
*
|
||||
* <p>By default, arguments to the {@link #value()} attribute will be processed using
|
||||
* an {@link XmlBeanDefinitionReader}, i.e. it is assumed that resources are Spring
|
||||
* {@literal <beans/>} XML files. Optionally, the {@link #reader()} attribute may be
|
||||
* {@code <beans/>} XML files. Optionally, the {@link #reader()} attribute may be
|
||||
* supplied, allowing the user to specify a different {@link BeanDefinitionReader}
|
||||
* implementation, such as
|
||||
* {@link org.springframework.beans.factory.support.PropertiesBeanDefinitionReader}.
|
||||
@@ -53,8 +53,8 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
public @interface ImportResource {
|
||||
|
||||
/**
|
||||
* Resource paths to import. Resource-loading prefixes such as {@literal classpath:} and
|
||||
* {@literal file:}, etc may be used.
|
||||
* Resource paths to import. Resource-loading prefixes such as {@code classpath:} and
|
||||
* {@code file:}, etc may be used.
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
|
||||
@@ -25,25 +25,25 @@ import java.lang.annotation.Inherited;
|
||||
|
||||
/**
|
||||
* Indicates whether a bean is to be lazily initialized.
|
||||
*
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated with
|
||||
* {@link Bean}.
|
||||
*
|
||||
*
|
||||
* <p>If this annotation is not present on a Component or Bean definition, eager
|
||||
* initialization will occur. If present and set to {@literal true}, the
|
||||
* initialization will occur. If present and set to {@code true}, the
|
||||
* Bean/Component will not be initialized until referenced by another bean or
|
||||
* explicitly retrieved from the enclosing
|
||||
* {@link org.springframework.beans.factory.BeanFactory}. If present and set to
|
||||
* {@literal false}, the bean will be instantiated on startup by bean factories
|
||||
* {@code false}, the bean will be instantiated on startup by bean factories
|
||||
* that perform eager initialization of singletons.
|
||||
*
|
||||
* <p>If Lazy is present on a {@link Configuration} class, this indicates that all
|
||||
* {@link Bean} methods within that {@literal Configuration} should be lazily
|
||||
* initialized. If Lazy is present and false on a Bean method within a
|
||||
* Lazy-annotated Configuration class, this indicates overriding the 'default
|
||||
* lazy' behavior and that the bean should be eagerly initialized.
|
||||
*
|
||||
*
|
||||
* <p>If Lazy is present on a {@link Configuration @Configuration} class, this
|
||||
* indicates that all {@link Bean @Bean} methods within that {@code @Configuration}
|
||||
* should be lazily initialized. If Lazy is present and false on a Bean method
|
||||
* within a Lazy-annotated Configuration class, this indicates overriding the
|
||||
* 'default lazy' behavior and that the bean should be eagerly initialized.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
* @see Primary
|
||||
|
||||
@@ -27,16 +27,16 @@ import java.lang.annotation.Target;
|
||||
* Indicates that a bean should be given preference when multiple candidates
|
||||
* are qualified to autowire a single-valued dependency. If exactly one 'primary'
|
||||
* bean exists among the candidates, it will be the autowired value.
|
||||
*
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated
|
||||
* with {@link Bean}.
|
||||
*
|
||||
*
|
||||
* <p>Using {@link Primary} at the class level has no effect unless component-scanning
|
||||
* is being used. If a {@link Primary}-annotated class is declared via XML,
|
||||
* {@link Primary} annotation metadata is ignored, and
|
||||
* {@literal <bean primary="true|false"/>} is respected instead.
|
||||
*
|
||||
* {@code <bean primary="true|false"/>} is respected instead.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
* @see Lazy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -16,42 +16,78 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
*
|
||||
* Components not @Profile-annotated will always be registered
|
||||
* ConfigurableEnvironment.setActiveProfiles(String...) sets which profiles are active
|
||||
* 'spring.profile.active' sets which profiles are active (typically as a -D system property)
|
||||
servlet context/init param)
|
||||
* ConfigurableEnvironment.setDefaultProfiles(String...) or 'spring.profile.default' property specifies one
|
||||
or more default profiles, e.g., 'default'
|
||||
* if 'default' is specified as a default profile, @Profile({"xyz,default}) means that beans will be
|
||||
registered if 'xyz' is active or if no profile is active
|
||||
* Indicates that a component is eligible for registration when one or more {@linkplain #value
|
||||
* specified profiles} are active.
|
||||
*
|
||||
* <p>A <em>profile</em> is a named logical grouping that may be activated programatically via
|
||||
* {@link ConfigurableEnvironment#setActiveProfiles} or declaratively through setting the
|
||||
* {@link AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME spring.profile.active} property,
|
||||
* usually through JVM system properties, as an environment variable, or for web applications
|
||||
* as a Servlet context parameter in {@code web.xml}.
|
||||
*
|
||||
* <p>The {@code @Profile} annotation may be used in any of the following ways:
|
||||
* <ul>
|
||||
* <li>as a type-level annotation on any class directly or indirectly annotated with
|
||||
* {@code @Component}, including {@link Configuration @Configuration} classes
|
||||
* <li>as a meta-annotation, for the purpose of composing custom stereotype annotations
|
||||
* </ul>
|
||||
*
|
||||
* <p>If a {@code @Configuration} class is marked with {@code @Profile}, all of the
|
||||
* {@code @Bean} methods and {@link Import @Import} annotations associated with that class will
|
||||
* be bypassed unless one or more the specified profiles are active. This is very similar to
|
||||
* the behavior in Spring XML: if the {@code profile} attribute of the {@code beans} element is
|
||||
* supplied e.g., {@code <beans profile="p1,p2">}, the {@code beans} element will not be parsed unless
|
||||
* profiles 'p1' and/or 'p2' have been activated. Likewise, if a {@code @Component} or
|
||||
* {@code @Configuration} class is marked with <code>@Profile({"p1", "p2"})</code>, that class will
|
||||
* not be registered/processed unless profiles 'p1' and/or 'p2' have been activated.
|
||||
*
|
||||
* <p>If the {@code @Profile} annotation is omitted, registration will occur, regardless of which,
|
||||
* if any, profiles are active.
|
||||
*
|
||||
* <p>When defining Spring beans via XML, the {@code "profile"} attribute of the {@code <beans>}
|
||||
* element may be used. See the documentation in {@code spring-beans-3.1.xsd} for details.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see ConfigurableEnvironment#setActiveProfiles
|
||||
* @see ConfigurableEnvironment#setDefaultProfiles
|
||||
* @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
|
||||
* @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ANNOTATION_TYPE, // @Profile may be used as a meta-annotation
|
||||
TYPE // In conjunction with @Component and its derivatives
|
||||
})
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Profile {
|
||||
|
||||
/**
|
||||
* @see #value()
|
||||
*/
|
||||
static final String CANDIDATE_PROFILES_ATTRIB_NAME = "value";
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
* The set profiles for which this component should be registered.
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
|
||||
static class Helper {
|
||||
/**
|
||||
* Return whether the given metadata includes Profile information, whether directly or
|
||||
* through meta-annotation.
|
||||
*/
|
||||
static boolean isProfileAnnotationPresent(AnnotationMetadata metadata) {
|
||||
return metadata.isAnnotated(Profile.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the String[] of candidate profiles from {@link Profile#value()}.
|
||||
*/
|
||||
static String[] getCandidateProfiles(AnnotationMetadata metadata) {
|
||||
return (String[])metadata.getAnnotationAttributes(Profile.class.getName()).get("value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.stereotype.Component;
|
||||
* the instance returned from the method.
|
||||
*
|
||||
* <p>In this context, scope means the lifecycle of an instance, such as
|
||||
* {@literal singleton}, {@literal prototype}, and so forth.
|
||||
* {@code singleton}, {@code prototype}, and so forth.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Chris Beams
|
||||
@@ -59,7 +59,7 @@ public @interface Scope {
|
||||
* and if so, whether the proxy should be interface-based or subclass-based.
|
||||
* <p>Defaults to {@link ScopedProxyMode#NO}, indicating that no scoped
|
||||
* proxy should be created.
|
||||
* <p>Analogous to {@literal <aop:scoped-proxy/>} support in Spring XML.
|
||||
* <p>Analogous to {@code <aop:scoped-proxy/>} support in Spring XML.
|
||||
*/
|
||||
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Annotation support for the Application Context, including JSR-250 "common"
|
||||
* annotations, component-scanning, and Java-based metadata for creating
|
||||
* Spring-managed objects.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.context.support.EnvironmentAwarePropertyPlaceholderConfigurer;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -35,32 +35,24 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
// as of Spring 3.1, the default for system-properties-mode is DELEGATE,
|
||||
// meaning that the attribute should be disregarded entirely, instead
|
||||
// deferring to the order of PropertySource objects in the enclosing
|
||||
// application context's Environment object
|
||||
if (!"DELEGATE".equals(element.getAttribute("system-properties-mode"))) {
|
||||
if (element.hasAttribute("system-properties-mode")) {
|
||||
return PropertyPlaceholderConfigurer.class;
|
||||
}
|
||||
|
||||
return EnvironmentAwarePropertyPlaceholderConfigurer.class;
|
||||
return PropertySourcesPlaceholderConfigurer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
super.doParse(element, builder);
|
||||
|
||||
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
|
||||
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
|
||||
|
||||
if (!"DELEGATE".equals(element.getAttribute("system-properties-mode"))) {
|
||||
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
|
||||
if (StringUtils.hasLength(systemPropertiesModeName)) {
|
||||
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
|
||||
}
|
||||
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
|
||||
if (StringUtils.hasLength(systemPropertiesModeName)) {
|
||||
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,11 +44,11 @@ public class EnvironmentAccessor implements PropertyAccessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Access provided {@literal target} object by calling its {@link Environment#getProperty(String)}
|
||||
* method with the provided {@literal name}.
|
||||
* Access the given target object by resolving the given property name against the given target
|
||||
* environment.
|
||||
*/
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((Environment)target).getProperty(name));
|
||||
return new TypedValue(((Environment)target).getPropertyResolver().getProperty(name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -206,8 +206,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
/** Statically specified listeners */
|
||||
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
|
||||
|
||||
/** TODO SPR-7508: document */
|
||||
private ConfigurableEnvironment environment = new DefaultEnvironment();
|
||||
/** Environment used by this context; initialized by {@link #createEnvironment()} */
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
|
||||
/**
|
||||
@@ -224,6 +224,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
public AbstractApplicationContext(ApplicationContext parent) {
|
||||
this.parent = parent;
|
||||
this.resourcePatternResolver = getResourcePatternResolver();
|
||||
this.environment = this.createEnvironment();
|
||||
}
|
||||
|
||||
|
||||
@@ -279,6 +280,14 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Default value is determined by {@link #createEnvironment()}. Replacing the
|
||||
* default with this method is one option but configuration through {@link
|
||||
* #getEnvironment()} should also be considered. In either case, such modifications
|
||||
* should be performed <em>before</em> {@link #refresh()}.
|
||||
* @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
|
||||
*/
|
||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
@@ -400,6 +409,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
return this.applicationListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new {@link DefaultEnvironment}.
|
||||
*/
|
||||
protected ConfigurableEnvironment createEnvironment() {
|
||||
return new DefaultEnvironment();
|
||||
}
|
||||
|
||||
public void refresh() throws BeansException, IllegalStateException {
|
||||
synchronized (this.startupShutdownMonitor) {
|
||||
@@ -456,7 +471,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
|
||||
/**
|
||||
* Prepare this context for refreshing, setting its startup date and
|
||||
* active flag.
|
||||
* active flag as well as performing any initialization of property sources.
|
||||
*/
|
||||
protected void prepareRefresh() {
|
||||
this.startupDate = System.currentTimeMillis();
|
||||
@@ -468,6 +483,18 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Refreshing " + this);
|
||||
}
|
||||
|
||||
// Initialize any placeholder property sources in the context environment
|
||||
initPropertySources();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Replace any stub property sources with actual instances.
|
||||
* @see org.springframework.core.env.PropertySource.StubPropertySource
|
||||
* @see org.springframework.web.context.support.WebApplicationContextUtils#initSerlvetPropertySources
|
||||
*/
|
||||
protected void initPropertySources() {
|
||||
// For subclasses: do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
|
||||
/**
|
||||
* Base class for {@link org.springframework.context.ApplicationContext}
|
||||
* implementations which are supposed to support multiple calls to {@literal refresh},
|
||||
* implementations which are supposed to support multiple calls to {@link #refresh()},
|
||||
* creating a new internal bean factory instance every time.
|
||||
* Typically (but not necessarily), such a context will be driven by
|
||||
* a set of config locations to load bean definitions from.
|
||||
@@ -50,7 +50,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
* and {@link FileSystemXmlApplicationContext}, which both derive from the
|
||||
* common {@link AbstractXmlApplicationContext} base class;
|
||||
* {@link org.springframework.context.annotation.AnnotationConfigApplicationContext}
|
||||
* supports {@literal @Configuration}-annotated classes as a source of bean definitions.
|
||||
* supports {@code @Configuration}-annotated classes as a source of bean definitions.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
@@ -182,7 +182,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
* Called for each {@link #refresh()} attempt.
|
||||
* <p>The default implementation creates a
|
||||
* {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
|
||||
* with the {@link #getInternalParentBeanFactory() internal bean factory} of this
|
||||
* with the {@linkplain #getInternalParentBeanFactory() internal bean factory} of this
|
||||
* context's parent as parent bean factory. Can be overridden in subclasses,
|
||||
* for example to customize DefaultListableBeanFactory's settings.
|
||||
* @return the bean factory for this context
|
||||
@@ -199,8 +199,8 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
* Customize the internal bean factory used by this context.
|
||||
* Called for each {@link #refresh()} attempt.
|
||||
* <p>The default implementation applies this context's
|
||||
* {@link #setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"}
|
||||
* and {@link #setAllowCircularReferences "allowCircularReferences"} settings,
|
||||
* {@linkplain #setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"}
|
||||
* and {@linkplain #setAllowCircularReferences "allowCircularReferences"} settings,
|
||||
* if specified. Can be overridden in subclasses to customize any of
|
||||
* {@link DefaultListableBeanFactory}'s settings.
|
||||
* @param beanFactory the newly created bean factory for this context
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
package org.springframework.context.support;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.SystemPropertyUtils;
|
||||
|
||||
/**
|
||||
* {@link AbstractRefreshableApplicationContext} subclass that adds common handling
|
||||
@@ -117,14 +117,9 @@ public abstract class AbstractRefreshableConfigApplicationContext extends Abstra
|
||||
* system property values if necessary. Applied to config locations.
|
||||
* @param path the original file path
|
||||
* @return the resolved file path
|
||||
* @see SystemPropertyUtils#resolveRequiredPlaceholders(String)
|
||||
*/
|
||||
protected String resolvePath(String path) {
|
||||
// TODO SPR-7508: note that ARAC cannot delegate to its beanFactory's environment
|
||||
// to call Environment.resolve[Required]Placeholders(String), as the bean factory
|
||||
// has not yet been initialized. This amounts to one more reason not to use the ARAC
|
||||
// hierarchy - it won't have early access to environment property resolution.
|
||||
return SystemPropertyUtils.resolvePlaceholders(path);
|
||||
return this.getEnvironment().getPropertyResolver().resolveRequiredPlaceholders(path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.support;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
|
||||
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: document
|
||||
*
|
||||
* Local properties are added as a property source in any case. Precedence is based
|
||||
* on the value of the {@link #setLocalOverride(boolean) localOverride} property.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see PropertyPlaceholderConfigurer
|
||||
* @see EnvironmentAwarePropertyOverrideConfigurer
|
||||
*/
|
||||
public class EnvironmentAwarePropertyPlaceholderConfigurer
|
||||
extends AbstractPropertyPlaceholderConfigurer implements EnvironmentAware {
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
private Environment wrappedEnvironment;
|
||||
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.wrappedEnvironment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PlaceholderResolver getPlaceholderResolver(Properties props) {
|
||||
return new PlaceholderResolver() {
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
return environment.getProperty(placeholderName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
Assert.notNull(this.wrappedEnvironment, "Environment must not be null. Did you call setEnvironment()?");
|
||||
environment = new AbstractEnvironment() { };
|
||||
|
||||
LinkedList<PropertySource<?>> propertySources = environment.getPropertySources();
|
||||
EnvironmentPropertySource environmentPropertySource =
|
||||
new EnvironmentPropertySource("wrappedEnvironment", wrappedEnvironment);
|
||||
|
||||
if (!this.localOverride) {
|
||||
propertySources.add(environmentPropertySource);
|
||||
}
|
||||
|
||||
if (this.localProperties != null) {
|
||||
int cx=0;
|
||||
for (Properties localProps : this.localProperties) {
|
||||
propertySources.add(new PropertiesPropertySource("localProperties"+cx++, localProps));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.localOverride) {
|
||||
propertySources.add(environmentPropertySource);
|
||||
}
|
||||
|
||||
super.postProcessBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
static class EnvironmentPropertySource extends PropertySource<Environment> {
|
||||
|
||||
public EnvironmentPropertySource(String name, Environment source) {
|
||||
super(name, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsProperty(String key) {
|
||||
return source.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String key) {
|
||||
return source.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
// TODO Auto-generated method stub
|
||||
return source.getPropertyCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
@@ -44,8 +44,8 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext that needs to be populated
|
||||
* through {@link #load} calls and then manually {@link #refresh refreshed}.
|
||||
* Create a new GenericXmlApplicationContext that needs to be
|
||||
* {@linkplain #load loaded} and then manually {@link #refresh refreshed}.
|
||||
*/
|
||||
public GenericXmlApplicationContext() {
|
||||
reader.setEnvironment(this.getEnvironment());
|
||||
@@ -91,8 +91,9 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom environment. Should be called before any call to
|
||||
* {@link #load}. TODO SPR-7508: document
|
||||
* {@inheritDoc}
|
||||
* <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
|
||||
* Should be called before any call to {@link #load}.
|
||||
*/
|
||||
@Override
|
||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
import org.springframework.core.env.PropertySourcesPropertyResolver;
|
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
|
||||
|
||||
/**
|
||||
* Specialization of {@link AbstractPropertyPlaceholderConfigurer}
|
||||
*
|
||||
* <p>Local properties are added as a property source in any case. Precedence is based
|
||||
* on the value of the {@link #setLocalOverride localOverride} property.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see AbstractPropertyPlaceholderConfigurer
|
||||
* @see PropertyPlaceholderConfigurer
|
||||
*/
|
||||
public class PropertySourcesPlaceholderConfigurer extends AbstractPropertyPlaceholderConfigurer
|
||||
implements EnvironmentAware {
|
||||
|
||||
/**
|
||||
* {@value} is the name given to the {@link PropertySource} for the set of
|
||||
* {@linkplain #mergeProperties() merged properties} supplied to this configurer.
|
||||
*/
|
||||
public static final String LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME = "localProperties";
|
||||
|
||||
private MutablePropertySources propertySources;
|
||||
|
||||
private PropertyResolver propertyResolver;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>{@code PropertySources} from this environment will be searched when replacing ${...} placeholders
|
||||
* @see #setPropertySources
|
||||
* @see #postProcessBeanFactory
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the set of {@link PropertySources} to be used by this configurer.
|
||||
* Setting this property indicates that environment property sources and local
|
||||
* properties should be ignored.
|
||||
* @see #postProcessBeanFactory
|
||||
*/
|
||||
public void setPropertySources(PropertySources propertySources) {
|
||||
this.propertySources = new MutablePropertySources(propertySources);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PlaceholderResolver getPlaceholderResolver(Properties props) {
|
||||
return new PlaceholderResolver() {
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
return propertyResolver.getProperty(placeholderName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Processing occurs by replacing ${...} placeholders in bean definitions by resolving each
|
||||
* against this configurer's set of {@link PropertySources}, which includes:
|
||||
* <ul>
|
||||
* <li>all {@linkplain Environment#getPropertySources environment property sources}, if an
|
||||
* {@code Environment} {@linkplain #setEnvironment is present}
|
||||
* <li>{@linkplain #mergeProperties merged local properties}, if {@linkplain #setLocation any}
|
||||
* {@linkplain #setLocations have} {@linkplain #setProperties been}
|
||||
* {@linkplain #setPropertiesArray specified}
|
||||
* <li>any property sources set by calling {@link #setPropertySources}
|
||||
* </ul>
|
||||
* <p>If {@link #setPropertySources} is called, <strong>environment and local properties will be
|
||||
* ignored</strong>. This method is designed to give the user fine-grained control over property
|
||||
* sources, and once set, the configurer makes no assumptions about adding additional sources.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
if (this.propertySources == null) {
|
||||
this.propertySources = new MutablePropertySources();
|
||||
if (this.environment != null) {
|
||||
this.propertySources.addAll(this.environment.getPropertySources());
|
||||
}
|
||||
try {
|
||||
PropertySource<?> localPropertySource =
|
||||
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, this.mergeProperties());
|
||||
if (this.localOverride) {
|
||||
this.propertySources.addFirst(localPropertySource);
|
||||
} else {
|
||||
this.propertySources.addLast(localPropertySource);
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new BeanInitializationException("Could not load properties", ex);
|
||||
}
|
||||
}
|
||||
|
||||
this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
|
||||
this.processProperties(beanFactory, this.propertyResolver.asProperties());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,8 +30,6 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.DefaultEnvironment;
|
||||
import org.springframework.jndi.JndiLocatorSupport;
|
||||
import org.springframework.jndi.TypeMismatchNamingException;
|
||||
|
||||
@@ -70,9 +68,6 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac
|
||||
/** Cache of the types of nonshareable resources: bean name --> bean type */
|
||||
private final Map<String, Class> resourceTypes = new HashMap<String, Class>();
|
||||
|
||||
/** TODO SPR-7508: should be JNDI-specific environment */
|
||||
private ConfigurableEnvironment environment = new DefaultEnvironment();
|
||||
|
||||
|
||||
public SimpleJndiBeanFactory() {
|
||||
setResourceRef(true);
|
||||
|
||||
Reference in New Issue
Block a user