Merge 3.1.0 development branch into trunk

Branch in question is 'env' branch from git://git.springsource.org/sandbox/cbeams.git; merged into
git-svn repository with:

    git merge -s recursive -Xtheirs --no-commit env

No merge conflicts, but did need to

    git rm spring-build

prior to committing.

With this change, Spring 3.1.0 development is now happening on SVN
trunk. Further commits to the 3.0.x line will happen in an as-yet
uncreated SVN branch.  3.1.0 snapshots will be available
per the usual nightly CI build from trunk.
This commit is contained in:
Chris Beams
2010-10-25 19:48:20 +00:00
parent b0ea2b13d2
commit f480333d31
211 changed files with 9876 additions and 623 deletions

View File

@@ -19,6 +19,7 @@ package org.springframework.context;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
@@ -53,7 +54,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.core.io.ResourceLoader
*/
public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory,
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**

View File

@@ -19,6 +19,8 @@ package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
/**
* SPI interface to be implemented by most if not all application contexts.
@@ -31,6 +33,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
* methods should only be used by startup and shutdown code.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 03.11.2003
*/
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle {
@@ -59,6 +62,11 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
/**
* Name of the {@link Environment} bean in the factory.
*/
String ENVIRONMENT_BEAN_NAME = "environment";
/**
* Name of the System properties bean in the factory.
* @see java.lang.System#getProperties()
@@ -87,6 +95,16 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
*/
void setParent(ApplicationContext parent);
/**
* TODO SPR-7508: document
*/
ConfigurableEnvironment getEnvironment();
/**
* TODO SPR-7508: document
*/
void setEnvironment(ConfigurableEnvironment environment);
/**
* Add a new BeanFactoryPostProcessor that will get applied to the internal
* bean factory of this application context on refresh, before any of the
@@ -105,7 +123,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* @see org.springframework.context.event.ContextRefreshedEvent
* @see org.springframework.context.event.ContextClosedEvent
*/
void addApplicationListener(ApplicationListener listener);
void addApplicationListener(ApplicationListener<?> listener);
/**
* Load or refresh the persistent representation of the configuration,

View File

@@ -0,0 +1,30 @@
/*
* 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;
import org.springframework.core.env.Environment;
/**
* TODO SPR-7515: document
*
* @author Chris Beams
*/
public interface EnvironmentAware {
void setEnvironment(Environment environment);
}

View File

@@ -24,6 +24,9 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
/**
* Convenient adapter for programmatic registration of annotated bean classes.
@@ -31,6 +34,7 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
* the same resolution of annotations but for explicitly registered classes only.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 3.0
* @see AnnotationConfigApplicationContext#register
*/
@@ -38,6 +42,8 @@ public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private Environment environment = new DefaultEnvironment();
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
@@ -61,9 +67,17 @@ public class AnnotatedBeanDefinitionReader {
return this.registry;
}
/**
* Set the Environment to use when registering classes.
* <p>The default is a {@link DefaultEnvironment}.
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Set the BeanNameGenerator to use for detected bean classes.
* <p>Default is a {@link AnnotationBeanNameGenerator}.
* <p>The default is a {@link AnnotationBeanNameGenerator}.
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
@@ -92,8 +106,45 @@ public class AnnotatedBeanDefinitionReader {
registerBean(annotatedClass, null, qualifiers);
}
private boolean hasEligibleProfile(AnnotationMetadata metadata) {
boolean hasEligibleProfile = false;
if (!metadata.hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])metadata.getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
return hasEligibleProfile;
}
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (!hasEligibleProfile(abd.getMetadata())) {
// TODO SPR-7508: log that this bean is being rejected on profile mismatch
return;
}
/*
if (metadata.hasAnnotation(Profile.class.getName())) {
if (this.environment == null) {
return;
}
Map<String, Object> profileAttribs = metadata.getAnnotationAttributes(Profile.class.getName());
String[] names = (String[]) profileAttribs.get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME);
boolean go=false;
for (String pName : names) {
if (this.environment.getActiveProfiles().contains(pName)) {
go = true;
}
}
if (!go) {
return;
}
}
*/
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

View File

@@ -16,8 +16,11 @@
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
@@ -46,6 +49,9 @@ 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
@@ -75,6 +81,15 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
refresh();
}
/**
* TODO SPR-7508: document
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
/**
* Set the BeanNameGenerator to use for detected bean classes.
@@ -94,7 +109,6 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
/**
* Register an annotated class to be processed. Allows for programmatically
* building a {@link AnnotationConfigApplicationContext}. Note that

View File

@@ -39,7 +39,7 @@ import org.springframework.util.ClassUtils;
* @author Chris Beams
* @since 2.5
* @see CommonAnnotationBeanPostProcessor
* @see org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
* @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
* @see org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
* @see org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor

View File

@@ -101,7 +101,7 @@ public @interface Bean {
* <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
* for any other scope.
* @see {@link org.springframework.context.ConfigurableApplicationContext#close()}
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
String destroyMethod() default "";

View File

@@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.BeanDefinitionDefaults;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
@@ -48,6 +49,7 @@ import org.springframework.util.PatternMatchUtils;
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
* @since 2.5
* @see AnnotationConfigApplicationContext#scan
* @see org.springframework.stereotype.Component
@@ -87,6 +89,10 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* {@link org.springframework.context.ApplicationContext} implementations.
* <p>If given a plain BeanDefinitionRegistry, the default ResourceLoader will be a
* {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
* <p>If the the passed-in bean factory also implements {@link EnvironmentCapable} its
* environment will be used by this reader. Otherwise, the reader will initialize and
* use a {@link DefaultEnvironment}. All ApplicationContext implementations are
* EnvironmentCapable, while normal BeanFactory implementations are not.
* @param registry the BeanFactory to load bean definitions into,
* in the form of a BeanDefinitionRegistry
* @param useDefaultFilters whether to include the default filters for the
@@ -96,6 +102,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* {@link org.springframework.stereotype.Controller @Controller} stereotype
* annotations.
* @see #setResourceLoader
* @see #setEnvironment
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(useDefaultFilters);
@@ -107,6 +114,11 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
if (this.registry instanceof ResourceLoader) {
setResourceLoader((ResourceLoader) this.registry);
}
// Inherit Environment if possible
if (this.registry instanceof EnvironmentCapable) {
setEnvironment(((EnvironmentCapable) this.registry).getEnvironment());
}
}

View File

@@ -25,11 +25,13 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -46,7 +48,6 @@ import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;
/**
* A component provider that scans the classpath from a base package. It then
@@ -59,18 +60,21 @@ import org.springframework.util.SystemPropertyUtils;
* @author Mark Fisher
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @author Chris Beams
* @since 2.5
* @see org.springframework.core.type.classreading.MetadataReaderFactory
* @see org.springframework.core.type.AnnotationMetadata
* @see ScannedGenericBeanDefinition
*/
public class ClassPathScanningCandidateComponentProvider implements ResourceLoaderAware {
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
protected final Log logger = LogFactory.getLog(getClass());
private Environment environment = new DefaultEnvironment();
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
@@ -110,6 +114,20 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
/**
* TODO SPR-7508: document
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* TODO SPR-7508: document
*/
public Environment getEnvironment() {
return this.environment;
}
/**
* Return the ResourceLoader that this component provider uses.
*/
@@ -261,7 +279,7 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
* @return the pattern specification to be used for package searching
*/
protected String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
return ClassUtils.convertClassNameToResourcePath(environment.resolveRequiredPlaceholders(basePackage));
}
/**
@@ -278,12 +296,28 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return true;
return hasEligibleProfile(metadataReader);
}
}
return false;
}
private boolean hasEligibleProfile(MetadataReader metadataReader) {
boolean hasEligibleProfile = false;
if (!metadataReader.getAnnotationMetadata().hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])metadataReader.getAnnotationMetadata().getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
return hasEligibleProfile;
}
/**
* Determine whether the given bean definition qualifies as candidate.
* <p>The default implementation checks whether the class is concrete

View File

@@ -0,0 +1,75 @@
/*
* 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.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
/**
* Configures component scanning directives for use with {@link Configuration}
* classes. Provides support parallel with Spring XML's
* &lt;context:component-scan&gt; element.
*
* TODO SPR-7508: complete documentation.
*
* @author Chris Beams
* @since 3.1
* @see FilterType
* @see Configuration
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
/** base packages to scan */
String[] value() default {};
Class<?>[] packageOf() default Void.class;
Class<? extends BeanNameGenerator> nameGenerator() default AnnotationBeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
String resourcePattern() default "**/*.class";
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
boolean useDefaultFilters() default true;
IncludeFilter[] includeFilters() default {};
ExcludeFilter[] excludeFilters() default {};
@Retention(RetentionPolicy.SOURCE)
@interface IncludeFilter {
FilterType type() default FilterType.ANNOTATION;
Class<?> value();
}
@Retention(RetentionPolicy.SOURCE)
@interface ExcludeFilter {
FilterType type() default FilterType.ANNOTATION;
Class<?> value();
}
}

View File

@@ -98,6 +98,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
// Delegate bean definition registration to scanner class.
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
scanner.setResourceLoader(readerContext.getResourceLoader());
scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

View File

@@ -57,6 +57,7 @@ import org.springframework.stereotype.Component;
* @see Bean
* @see ConfigurationClassPostProcessor
* @see AnnotationConfigApplicationContext
* @see org.springframework.context.annotation.Profile
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)

View File

@@ -105,7 +105,6 @@ final class ConfigurationClass {
return this.importedResources;
}
public void validate(ProblemReporter problemReporter) {
// An @Bean method may only be overloaded through inheritance. No single
// @Configuration class may declare two @Bean methods with the same name.

View File

@@ -27,6 +27,7 @@ import java.util.Stack;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
@@ -63,14 +64,18 @@ class ConfigurationClassParser {
private final Set<ConfigurationClass> configurationClasses =
new LinkedHashSet<ConfigurationClass>();
private final Environment environment;
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
* to populate the set of configuration classes.
*/
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter) {
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
}
@@ -95,8 +100,28 @@ class ConfigurationClassParser {
processConfigurationClass(new ConfigurationClass(clazz, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
boolean hasEligibleProfile = false;
if (this.environment == null) {
hasEligibleProfile = true;
} else {
if (!configClass.getMetadata().hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])configClass.getMetadata().getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
}
if (!hasEligibleProfile) {
//logger.debug("TODO SPR-7508: issue debug statement that this class is being excluded");
// make sure XML has a symmetrical statement as well
return;
}
AnnotationMetadata metadata = configClass.getMetadata();
while (metadata != null) {
doProcessConfigurationClass(configClass, metadata);
@@ -120,6 +145,7 @@ class ConfigurationClassParser {
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
}
this.configurationClasses.add(configClass);
}

View File

@@ -16,6 +16,7 @@
package org.springframework.context.annotation;
import java.awt.dnd.Autoscroll;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -38,7 +39,9 @@ import org.springframework.beans.factory.parsing.SourceExtractor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.Assert;
@@ -61,7 +64,8 @@ import org.springframework.util.ClassUtils;
* @author Juergen Hoeller
* @since 3.0
*/
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanClassLoaderAware {
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
BeanClassLoaderAware, EnvironmentAware {
/** Whether the CGLIB2 library is present on the classpath */
private static final boolean cglibAvailable = ClassUtils.isPresent(
@@ -84,6 +88,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private boolean postProcessBeanFactoryCalled = false;
private Environment environment;
/**
* Set the {@link SourceExtractor} to use for generated bean definitions
@@ -121,8 +127,12 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
return Ordered.HIGHEST_PRECEDENCE + 1; // make room for AutoScanningBeanDefinitionRegistrar
}
@@ -180,7 +190,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
// Populate a new configuration model by parsing each @Configuration classes
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter);
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment);
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 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.
@@ -16,19 +16,39 @@
package org.springframework.context.annotation;
import org.springframework.core.type.filter.AssignableTypeFilter;
/**
* Enumeration of the valid type filters to be added for annotation-driven configuration.
* Enumeration of the type filters that may be used in conjunction with
* {@link ComponentScan @ComponentScan}.
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
* @since 2.5
* @see ComponentScan
* @see ComponentScan.IncludeFilter
* @see ComponentScan.ExcludeFilter
* @see org.springframework.core.type.filter.TypeFilter
*/
public enum FilterType {
/**
* Filter candidates marked with a given annotation.
* @see org.springframework.core.type.filter.AnnotationTypeFilter
*/
ANNOTATION,
/**
* Filter candidates assignable to a given type.
* @see AssignableTypeFilter
*/
ASSIGNABLE_TYPE,
ASPECTJ_PATTERN,
REGEX_PATTERN,
/** Filter candidates using a given custom
* {@link org.springframework.core.type.filter.TypeFilter} implementation
*/
CUSTOM
}

View File

@@ -0,0 +1,46 @@
/*
* 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.annotation;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Chris Beams
* @since 3.1
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ANNOTATION_TYPE, // @Profile may be used as a meta-annotation
TYPE // In conjunction with @Component and its derivatives
})
public @interface Profile {
/**
* @see #value()
*/
static final String CANDIDATE_PROFILES_ATTRIB_NAME = "value";
/**
* TODO SPR-7508: document
*/
String[] value();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 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.
@@ -20,6 +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.util.StringUtils;
/**
@@ -27,15 +28,24 @@ import org.springframework.util.StringUtils;
*
* @author Juergen Hoeller
* @author Dave Syer
* @author Chris Beams
* @since 2.5
*/
class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
@Override
protected Class getBeanClass(Element element) {
return PropertyPlaceholderConfigurer.class;
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"))) {
return PropertyPlaceholderConfigurer.class;
}
return EnvironmentAwarePropertyPlaceholderConfigurer.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
@@ -44,9 +54,11 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
if (StringUtils.hasLength(systemPropertiesModeName)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
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);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.expression;
import org.springframework.core.env.Environment;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
/**
* Read-only EL property accessor that knows how to retrieve keys
* of a Spring {@link Environment} instance.
*
* @author Chris Beams
* @since 3.1
*/
public class EnvironmentAccessor implements PropertyAccessor {
public Class<?>[] getSpecificTargetClasses() {
return new Class[] { Environment.class };
}
/**
* Can read any {@link Environment}, thus always returns true.
* @return true
*/
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return true;
}
/**
* Access provided {@literal target} object by calling its {@link Environment#getProperty(String)}
* method with the provided {@literal name}.
*/
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
return new TypedValue(((Environment)target).getProperty(name));
}
/**
* Read only.
* @return false
*/
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return false;
}
/**
* Read only. No-op.
*/
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
}
}

View File

@@ -126,6 +126,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
sec.addPropertyAccessor(new BeanFactoryAccessor());
sec.addPropertyAccessor(new MapAccessor());
sec.addPropertyAccessor(new EnvironmentAccessor());
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();

View File

@@ -18,7 +18,6 @@ package org.springframework.context.support;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@@ -33,7 +32,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
@@ -54,6 +52,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.MessageSource;
@@ -73,6 +72,8 @@ import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -203,7 +204,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private ApplicationEventMulticaster applicationEventMulticaster;
/** Statically specified listeners */
private Set<ApplicationListener> applicationListeners = new LinkedHashSet<ApplicationListener>();
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
/** TODO SPR-7508: document */
private ConfigurableEnvironment environment = new DefaultEnvironment();
/**
@@ -271,6 +275,14 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return this.parent;
}
public ConfigurableEnvironment getEnvironment() {
return this.environment;
}
public void setEnvironment(ConfigurableEnvironment environment) {
this.environment = environment;
}
/**
* Return this context's internal bean factory as AutowireCapableBeanFactory,
* if already available.
@@ -363,6 +375,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
}
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
@@ -371,7 +384,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return this.beanFactoryPostProcessors;
}
public void addApplicationListener(ApplicationListener listener) {
public void addApplicationListener(ApplicationListener<?> listener) {
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
@@ -383,7 +396,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the list of statically specified ApplicationListeners.
*/
public Collection<ApplicationListener> getApplicationListeners() {
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
@@ -481,7 +494,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
@@ -489,6 +502,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
@@ -505,54 +519,16 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
// Register default environment beans.
if (!beanFactory.containsBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
Map systemProperties;
try {
systemProperties = System.getProperties();
}
catch (AccessControlException ex) {
systemProperties = new ReadOnlySystemAttributesMap() {
@Override
protected String getSystemAttribute(String propertyName) {
try {
return System.getProperty(propertyName);
}
catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info("Not allowed to obtain system property [" + propertyName + "]: " +
ex.getMessage());
}
return null;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
Map<String,String> systemEnvironment;
try {
systemEnvironment = System.getenv();
}
catch (AccessControlException ex) {
systemEnvironment = new ReadOnlySystemAttributesMap() {
@Override
protected String getSystemAttribute(String variableName) {
try {
return System.getenv(variableName);
}
catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info("Not allowed to obtain system environment variable [" + variableName + "]: " +
ex.getMessage());
}
return null;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
@@ -664,6 +640,15 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
/**
* Common location for subclasses to call and receive registration of standard
* {@link BeanFactoryPostProcessor} bean definitions.
*
* @param registry subclass BeanDefinitionRegistry
*/
protected void registerStandardBeanFactoryPostProcessors(BeanDefinitionRegistry registry) {
}
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
@@ -848,7 +833,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener listener : getApplicationListeners()) {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
@@ -869,7 +854,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @deprecated as of Spring 3.0, in favor of {@link #addApplicationListener}
*/
@Deprecated
protected void addListener(ApplicationListener listener) {
protected void addListener(ApplicationListener<?> listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
@@ -1099,7 +1084,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().isPrototype(name);
}
public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
return getBeanFactory().isTypeMatch(name, targetType);
}
@@ -1128,11 +1113,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().getBeanDefinitionNames();
}
public String[] getBeanNamesForType(Class type) {
public String[] getBeanNamesForType(Class<?> type) {
return getBeanFactory().getBeanNamesForType(type);
}
public String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit) {
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
}
@@ -1347,7 +1332,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>();
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanDefinition.isSingleton()) {
this.singletonNames.put(beanName, Boolean.TRUE);
}
@@ -1363,7 +1348,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
addApplicationListener((ApplicationListener) bean);
addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !containsBean(beanName)) {

View File

@@ -53,6 +53,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
* supports {@literal @Configuration}-annotated classes as a source of bean definitions.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 1.1.3
* @see #loadBeanDefinitions
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory
@@ -217,6 +218,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
}
beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
registerStandardBeanFactoryPostProcessors(beanFactory);
}
/**

View File

@@ -117,9 +117,13 @@ 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 org.springframework.util.SystemPropertyUtils#resolvePlaceholders
* @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);
}

View File

@@ -83,6 +83,7 @@ public abstract class AbstractXmlApplicationContext extends AbstractRefreshableC
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

View File

@@ -27,8 +27,10 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.util.StringValueResolver;
/**
@@ -37,18 +39,24 @@ import org.springframework.util.StringValueResolver;
* implement the {@link ResourceLoaderAware}, {@link MessageSourceAware},
* {@link ApplicationEventPublisherAware} and/or
* {@link ApplicationContextAware} interfaces.
* If all of them are implemented, they are satisfied in the given order.
*
* <p>Also delegates the ApplicationContext {@link Environment} instance
* to beans that implement {@link EnvironmentAware}.
*
* <p>Implemented interfaces are satisfied in order of their mention above.
*
* <p>Application contexts will automatically register this with their
* underlying bean factory. Applications do not use this directly.
*
* @author Juergen Hoeller
* @author Costin Leau
* @author Chris Beams
* @since 10.10.2003
* @see org.springframework.context.ResourceLoaderAware
* @see org.springframework.context.MessageSourceAware
* @see org.springframework.context.ApplicationEventPublisherAware
* @see org.springframework.context.ApplicationContextAware
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.context.support.AbstractApplicationContext#refresh()
*/
class ApplicationContextAwareProcessor implements BeanPostProcessor {
@@ -105,6 +113,9 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
}
public Object postProcessAfterInitialization(Object bean, String beanName) {

View File

@@ -0,0 +1,115 @@
/*
* 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();
}
}
}

View File

@@ -28,6 +28,7 @@ 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;
@@ -78,6 +79,7 @@ import org.springframework.util.Assert;
* from the {@link AbstractRefreshableApplicationContext} base class.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 1.1.2
* @see #registerBeanDefinition
* @see #refresh()
@@ -102,6 +104,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
this.beanFactory = new DefaultListableBeanFactory();
this.beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
this.beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
registerStandardBeanFactoryPostProcessors(this.beanFactory);
}
/**
@@ -181,7 +184,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* delegate all <code>getResource</code> calls to the given ResourceLoader.
* If not set, default resource loading will apply.
* <p>The main reason to specify a custom ResourceLoader is to resolve
* resource paths (withour URL prefix) in a specific fashion.
* resource paths (without URL prefix) in a specific fashion.
* The default behavior is to resolve such paths as class path locations.
* To resolve resource paths as file system locations, specify a
* FileSystemResourceLoader here.

View File

@@ -17,7 +17,7 @@
package org.springframework.context.support;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
/**
@@ -47,6 +47,7 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
* through {@link #load} calls and then manually {@link #refresh refreshed}.
*/
public GenericXmlApplicationContext() {
reader.setEnvironment(this.getEnvironment());
}
/**
@@ -88,6 +89,15 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
this.reader.setValidating(validating);
}
/**
* Set a custom environment. Should be called before any call to
* {@link #load}. TODO SPR-7508: document
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(this.getEnvironment());
}
/**
* Load bean definitions from the given XML resources.

View File

@@ -1,98 +0,0 @@
/*
* 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.support;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* Read-only {@code Map<String, String>} implementation that is backed by system properties or environment
* variables.
*
* <p>Used by {@link AbstractApplicationContext} when a {@link SecurityManager} prohibits access to {@link
* System#getProperties()} or {@link System#getenv()}.
*
* @author Arjen Poutsma
* @since 3.0
*/
abstract class ReadOnlySystemAttributesMap implements Map<String, String> {
public boolean containsKey(Object key) {
return get(key) != null;
}
public String get(Object key) {
if (key instanceof String) {
String attributeName = (String) key;
return getSystemAttribute(attributeName);
}
else {
return null;
}
}
public boolean isEmpty() {
return false;
}
/**
* Template method that returns the underlying system attribute.
*
* <p>Implementations typically call {@link System#getProperty(String)} or {@link System#getenv(String)} here.
*/
protected abstract String getSystemAttribute(String attributeName);
// Unsupported
public int size() {
throw new UnsupportedOperationException();
}
public String put(String key, String value) {
throw new UnsupportedOperationException();
}
public boolean containsValue(Object value) {
throw new UnsupportedOperationException();
}
public String remove(Object key) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}
public Set<String> keySet() {
throw new UnsupportedOperationException();
}
public void putAll(Map<? extends String, ? extends String> m) {
throw new UnsupportedOperationException();
}
public Collection<String> values() {
throw new UnsupportedOperationException();
}
public Set<Entry<String, String>> entrySet() {
throw new UnsupportedOperationException();
}
}

View File

@@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
@@ -29,6 +30,8 @@ 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;
@@ -67,6 +70,9 @@ 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);
@@ -94,6 +100,11 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac
}
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
public Object getBean(String name) throws BeansException {
return getBean(name, Object.class);
}

View File

@@ -1,13 +1,17 @@
http\://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/context/spring-context-3.0.xsd=org/springframework/context/config/spring-context-3.0.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-3.0.xsd
http\://www.springframework.org/schema/context/spring-context-3.1.xsd=org/springframework/context/config/spring-context-3.1.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-3.1.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee-3.0.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-3.1.xsd=org/springframework/ejb/config/spring-jee-3.1.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.1.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang-3.0.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-3.1.xsd=org/springframework/scripting/config/spring-lang-3.1.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-3.1.xsd
http\://www.springframework.org/schema/task/spring-task-3.0.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd
http\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd
http\://www.springframework.org/schema/task/spring-task-3.1.xsd=org/springframework/scheduling/config/spring-task-3.1.xsd
http\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.1.xsd

View File

@@ -0,0 +1,500 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/context"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/context"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" />
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" />
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's application
context support. Effects the activation of various configuration styles
for the containing Spring ApplicationContext.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType name="propertyPlaceholder">
<xsd:attribute name="location" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The location of the properties file to resolve placeholders against, as a Spring
resource location: a URL, a "classpath:" pseudo URL, or a relative file path.
Multiple locations may be specified, separated by commas. If neither location nor properties-ref is
specified, placeholders will be resolved against system properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="properties-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.util.Properties"><![CDATA[
The bean name of a Java Properties object that will be used for property substitution.
If neither location nor properties-ref is specified, placeholders will be resolved against system properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="file-encoding" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the encoding to use for parsing properties files. Default is none,
using the java.util.Properties default encoding. Only applies to classic
properties files, not to XML files.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:integer">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the order for this placeholder configurer. If more than one is present in a context
the order can be important since the first one to be match a placeholder will win. Often used
in conjunction with
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-resource-not-found" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies if failure to find the property resource location should be ignored. Default
is "false", meaning that if there is no file in the location specified an exception will
be raised at runtime.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-unresolvable" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies if failure to find the property value to replace a key should be ignored. Default
is "false", meaning that this placeholder configurer will raise an exception if it cannot resolve
a key. Set to "true" to allow the configurer to pass on the key to any others in
the context that have not yet visited the key in question.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="local-override" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies whether local properties override properties from files. Default
is "false": Properties from files override local defaults.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:element name="property-placeholder">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates replacement of ${...} placeholders, resolved against the specified properties file or
Properties object (if any). Defines an EnvironmentAwarePropertyPlaceholderConfigurer within the context.
For backward compatibility with versions earlier than Spring 3.1, a PropertyPlaceholderConfigurer will be
registered if the 'system-properties-mode' attribute has been explicitly assigned a value.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="propertyPlaceholder">
<xsd:attribute name="system-properties-mode" default="DELEGATE">
<xsd:annotation>
<xsd:documentation><![CDATA[
If set to any value other than DELEGATE, register a PropertyPlaceholderConfigurer bean and call
its setSystemPropertiesModeName() method with the value. If set to DELEGATE (the default), register
an EnvironmentAwarePropertyPlaceholderConfigurer and ignore the setting altogether, instead delegating
to the enclosing application context's Environment object and its collection of PropertySource objects
which may or may not include system properties and environment variables.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="DELEGATE"/>
<xsd:enumeration value="NEVER"/>
<xsd:enumeration value="FALLBACK"/>
<xsd:enumeration value="OVERRIDE"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="property-override">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates pushing of override values into bean properties, based on configuration
lines of the following format: beanName.property=value
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="propertyPlaceholder" />
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="annotation-config">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.
Note: This tag does not activate processing of Spring's @Transactional or EJB3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="component-scan">
<xsd:annotation>
<xsd:documentation><![CDATA[
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository,
@Service, and @Controller stereotypes will be detected.
Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.
Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definition
being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include-filter" type="filterType"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls which eligible types to include for component scanning.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="exclude-filter" type="filterType"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls which eligible types to exclude for component scanning.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="base-package" type="xsd:string"
use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma-separated list of packages to scan for annotated components.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resource-pattern" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls the class files eligible for component detection. Defaults to "**/*.class", the recommended value.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="use-default-filters" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service,
or @Controller should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="annotation-config" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.beans.factory.support.BeanNameGenerator" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope-resolver" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the ScopeMetadataResolver to be used for resolving the scope of
detected components.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.context.annotation.ScopeMetadataResolver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scoped-proxy">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether proxies should be generated for detected components, which may be necessary
when using scopes in a proxy-style fashion. Default is to generate no such proxies.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="no" />
<xsd:enumeration value="interfaces" />
<xsd:enumeration value="targetClass" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="load-time-weaver">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates a Spring LoadTimeWeaver for this application context, available as
a bean with the name "loadTimeWeaver". Any bean that implements the
LoadTimeWeaverAware interface will then receive the LoadTimeWeaver reference
automatically; for example, Spring's JPA bootstrap support.
The default weaver is determined automatically. As of Spring 2.5: detecting
Sun's GlassFish, Oracle's OC4J, Spring's VM agent and any ClassLoader
supported by Spring's ReflectiveLoadTimeWeaver (for example, the
TomcatInstrumentableClassLoader).
The activation of AspectJ load-time weaving is specified via a simple flag
(the 'aspectj-weaving' attribute), with the AspectJ class transformer
registered through Spring's LoadTimeWeaver. AspectJ weaving will be activated
by default if a "META-INF/aop.xml" resource is present in the classpath.
This also activates the current application context for applying dependency
injection to non-managed classes that are instantiated outside of the Spring
bean factory (typically classes annotated with the @Configurable annotation).
This will only happen if the AnnotationBeanConfigurerAspect is on the classpath
(i.e. spring-aspects.jar), effectively activating "spring-configured" by default.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="weaver-class" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified classname of the LoadTimeWeaver that is to be activated.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="aspectj-weaving" default="autodetect">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="on">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches Spring-based AspectJ load-time weaving on.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="off">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches Spring-based AspectJ load-time weaving off.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="autodetect">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches AspectJ load-time weaving on if a "META-INF/aop.xml" resource
is present in the classpath. If there is no such resource, then AspectJ
load-time weaving will be switched off.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="spring-configured">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect">
<![CDATA[
Signals the current application context to apply dependency injection
to non-managed classes that are instantiated outside of the Spring bean
factory (typically classes annotated with the @Configurable annotation).
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
</xsd:element>
<xsd:element name="mbean-export">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.jmx.export.annotation.AnnotationMBeanExporter"><![CDATA[
Activates default exporting of MBeans by detecting standard MBeans in the Spring
context as well as @ManagedResource annotations on Spring-defined beans.
The resulting MBeanExporter bean is defined under the name "mbeanExporter".
Alternatively, consider defining a custom AnnotationMBeanExporter bean explicitly.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="default-domain" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The default domain to use when generating JMX ObjectNames.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="server" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name of the MBeanServer to which MBeans should be exported.
Default is to use the platform's default MBeanServer (autodetecting
WebLogic 9+, WebSphere 5.1+ and the JDK 1.5+ platform MBeanServer).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="registration">
<xsd:annotation>
<xsd:documentation><![CDATA[
The registration behavior, indicating how to deal with existing MBeans
of the same name: fail with an exception, ignore and keep the existing
MBean, or replace the existing one with the new MBean.
Default is to fail with an exception.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="failOnExisting" />
<xsd:enumeration value="ignoreExisting" />
<xsd:enumeration value="replaceExisting" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="mbean-server">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.jmx.support.MBeanServerFactoryBean"><![CDATA[
Exposes a default MBeanServer for the current platform.
Autodetects WebLogic 9+, WebSphere 6.1+ and the JDK 1.5+ platform MBeanServer.
The default bean name for the exposed MBeanServer is "mbeanServer".
This may be customized through specifying the "id" attribute.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="javax.management.MBeanServer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="agent-id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The agent id of the target MBeanServer, if any.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="filterType">
<xsd:attribute name="type" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls the type of filtering to apply to the expression.
"annotation" indicates an annotation to be present at the type level in target components;
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
"aspectj" indicates an AspectJ type expression to be matched by the target components;
"regex" indicates a regex expression to be matched by the target components' class names;
"custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="annotation" />
<xsd:enumeration value="assignable" />
<xsd:enumeration value="aspectj" />
<xsd:enumeration value="regex" />
<xsd:enumeration value="custom" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="expression" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the filter expression, the type of which is indicated by "type".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/jee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/jee"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines configuration elements for access to traditional Java EE components
such as JNDI resources and EJB session beans.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="jndi-lookup">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
Exposes an object reference via a JNDI lookup.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="jndiLocatingType">
<xsd:attribute name="cache" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the object returned from the JNDI lookup is cached
after the first lookup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expected-type" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The type that the located JNDI object is supposed to be assignable
to, if indeed any.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lookup-on-startup" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the JNDI lookup is performed immediately on startup
(if true, the default), or on first access (if false).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="proxy-interface" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The proxy interface to use for the JNDI object.
Needs to be specified because the actual JNDI object type is not
known in advance in case of a lazy lookup.
Typically used in conjunction with "lookupOnStartup"=false and/or
"cache"=false.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-value" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specify a default literal value to fall back to if the JNDI lookup fails.
This is typically used for literal values in scenarios where the JNDI environment
might define specific config settings but those are not required to be present.
Default is none. Note: This is only supported for lookup on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specify a default bean reference to fall back to if the JNDI lookup fails.
This might for example point to a local fallback DataSource.
Default is none. Note: This is only supported for lookup on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="local-slsb" type="ejbType">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"><![CDATA[
Exposes a reference to a local EJB Stateless SessionBean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="remote-slsb">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"><![CDATA[
Exposes a reference to a remote EJB Stateless SessionBean.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="ejbType">
<xsd:attribute name="home-interface" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The home interface that will be narrowed to before performing
the parameterless SLSB create() call that returns the actual
SLSB proxy.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="refresh-home-on-connect-failure" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether to refresh the EJB home on connect failure.
Can be turned on to allow for hot restart of the EJB server.
If a cached EJB home throws an RMI exception that indicates a
remote connect failure, a fresh home will be fetched and the
invocation will be retried.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-session-bean" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether to cache the actual session bean object.
Off by default for standard EJB compliance. Turn this flag
on to optimize session bean access for servers that are
known to allow for caching the actual session bean object.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<!-- base types -->
<xsd:complexType name="jndiLocatingType" abstract="true">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element name="environment" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
The newline-separated, key-value pairs for the JNDI environment
(in standard Properties format, namely 'key=value' pairs)
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="environment-ref" type="environmentRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to JNDI environment properties, indicating the name of a
shared bean of type [java.util.Properties}.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="jndi-name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The JNDI name to look up. This may be a fully-qualified JNDI path
or a local Java EE environment naming context path in which case the
prefix "java:comp/env/" will be prepended if applicable.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resource-ref" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the lookup occurs in a Java EE container, i.e. if the
prefix "java:comp/env/" needs to be added if the JNDI name doesn't
already contain it. Default is "true" (since Spring 2.5).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-access-context" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set whether to expose the JNDI environment context for all access to the target
EJB, i.e. for all method invocations on the exposed object reference.
Default is "false", i.e. to only expose the JNDI context for object lookup.
Switch this flag to "true" in order to expose the JNDI environment (including
the authorization context) for each EJB invocation, as needed by WebLogic
for EJBs with authorization requirements.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="ejbType">
<xsd:complexContent>
<xsd:extension base="jndiLocatingType">
<xsd:attribute name="lookup-home-on-startup" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the lookup of the EJB home object is performed
immediately on startup (if true, the default), or on first access
(if false).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-home" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the EJB home object is cached once it has been located.
On by default; turn this flag off to always reobtain fresh home objects.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="business-interface" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The business interface of the EJB being proxied.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:simpleType name="environmentRefType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java.util.Properties"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/task"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/task"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the elements used in the Spring Framework's support for task execution and scheduling.
]]></xsd:documentation>
</xsd:annotation>
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:element name="annotation-driven">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. If present,
a proxy will be generated for executing the annotated methods asynchronously.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="executor" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the java.util.Executor instance to use when invoking asynchronous methods.
If not provided, an instance of org.springframework.core.task.SimpleAsyncTaskExecutor
will be used by default
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scheduler" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the org.springframework.scheduling.TaskScheduler or
java.util.ScheduledExecutorService instance to use when invoking scheduled
methods. If no reference is provided, a TaskScheduler backed by a single
thread scheduled executor will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scheduler">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a ThreadPoolTaskScheduler instance with configurable pool size.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name for the generated ThreadPoolTaskScheduler instance.
It will also be used as the default thread name prefix.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pool-size" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The size of the ScheduledExecutorService's thread pool. The default is 1.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="executor">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a ThreadPoolTaskExecutor instance with configurable pool size,
queue-capacity, keep-alive, and rejection-policy values.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name for the generated ThreadPoolTaskExecutor instance.
This value will also be used as the thread name prefix which is why it is
required even when defining the executor as an inner bean: The executor
won't be directly accessible then but will nevertheless use the specified
id as the thread name prefix of the threads that it manages.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pool-size" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The size of the executor's thread pool as either a single value or a range
(e.g. 5-10). If no bounded queue-capacity value is provided, then a max value
has no effect unless the range is specified as 0-n. In that case, the core pool
will have a size of n, but the 'allowCoreThreadTimeout' flag will be set to true.
If a queue-capacity is provided, then the lower bound of a range will map to the
core size and the upper bound will map to the max size. If this attribute is not
provided, the default core size will be 1, and the default max size will be
Integer.MAX_VALUE (i.e. unbounded).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="queue-capacity" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Queue capacity for the ThreadPoolTaskExecutor. If not specified, the default will
be Integer.MAX_VALUE (i.e. unbounded).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keep-alive" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Keep-alive time in seconds. Inactive threads that have been created beyond the
core size will timeout after the specified number of seconds elapse. If the
executor has an unbounded queue capacity and a size range represented as 0-n,
then the core threads will also be configured to timeout when inactive.
Otherwise, core threads will not ever timeout.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="rejection-policy" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The RejectedExecutionHandler type. When a bounded queue cannot accept any
additional tasks, this determines the behavior. While the default is ABORT,
consider using CALLER_RUNS to throttle inbound tasks. In other words, by forcing
the caller to run the task itself, it will not be able to provide another task
until after it completes the task at hand. In the meantime, one or more tasks
may be removed from the queue. Alternatively, if it is not critical to run every
task, consider using DISCARD to drop the current task or DISCARD_OLDEST to drop
the task at the head of the queue.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ABORT"/>
<xsd:enumeration value="CALLER_RUNS"/>
<xsd:enumeration value="DISCARD"/>
<xsd:enumeration value="DISCARD_OLDEST"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scheduled-tasks">
<xsd:annotation>
<xsd:documentation><![CDATA[
Top-level element that contains one or more task sub-elements to be
managed by a given TaskScheduler.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="scheduled" type="scheduledTaskType" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="scheduler" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to an instance of TaskScheduler to manage the provided tasks. If not specified,
the default value will be a wrapper for a single-threaded Executor.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.scheduling.TaskScheduler"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="scheduledTaskType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Element defining a scheduled method-invoking task and its corresponding trigger.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="cron" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
A cron-based trigger. See the org.springframework.scheduling.support.CronSequenceGenerator
JavaDoc for example patterns.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="fixed-delay" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
An interval-based trigger where the interval is measured from the completion time of the
previous task. The time unit value is measured in milliseconds.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="fixed-rate" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
An interval-based trigger where the interval is measured from the start time of the
previous task. The time unit value is measured in milliseconds.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to an object that provides a method to be invoked.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref" />
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="method" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method to be invoked.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-method type-ref="@ref"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/lang"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/lang"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the elements used in the Spring Framework's dynamic language
support, which allows bean definitions that are backed by classes
written in a language other than Java.
]]></xsd:documentation>
</xsd:annotation>
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:element name="defaults">
<xsd:annotation>
<xsd:documentation><![CDATA[
Default settings for any scripted beans registered within this context.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="defaultableAttributes"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="groovy" type="customizableScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a Groovy class definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jruby" type="dynamicScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a JRuby class definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="bsh" type="dynamicScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a BeanShell script.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- Script Types -->
<xsd:complexType name="simpleScriptType">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element name="inline-script" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
The source code for the dynamic language-backed bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="property" type="beans:propertyType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Dynamic language-backed bean definitions can have zero or more properties.
Property elements correspond to JavaBean setter methods exposed
by the bean classes. Spring supports primitives, references to other
beans in the same or related factories, lists, maps and properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attributeGroup ref="defaultableAttributes"/>
<xsd:attribute name="script-source" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.io.Resource"><![CDATA[
The resource containing the script for the dynamic language-backed bean.
Examples might be '/WEB-INF/scripts/Anais.groovy', 'classpath:Nin.bsh', etc.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of this scripted bean as an alias or replacement for the id.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this scripted bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton".
Singletons are most commonly used, and are ideal for multi-threaded
service objects. Further scopes, such as "request" or "session", might
be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="autowire" default="default">
<xsd:annotation>
<xsd:documentation><![CDATA[
The autowire mode for the scripted bean.
Analogous to the 'autowire' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="default"/>
<xsd:enumeration value="no"/>
<xsd:enumeration value="byName"/>
<xsd:enumeration value="byType"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="depends-on" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The names of the beans that this bean depends on being initialized.
The bean factory will guarantee that these beans get initialized
before this bean.
Note that dependencies are normally expressed through bean properties.
This property should just be necessary other kinds of dependencies
like statics (*ugh*) or database preparation on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="init-method" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of an initialization method defined on the scripted bean.
Analogous to the 'init-method' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="destroy-method" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of a destruction method defined on the scripted bean.
Analogous to the 'destroy-method' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="dynamicScriptType">
<xsd:complexContent>
<xsd:extension base="simpleScriptType">
<xsd:attribute name="script-interfaces">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The Java interfaces that the dynamic language-backed object is to expose; comma-delimited.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="customizableScriptType">
<xsd:complexContent>
<xsd:extension base="simpleScriptType">
<xsd:attribute name="customizer-ref">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to a GroovyObjectCustomizer or similar customizer bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:attributeGroup name="defaultableAttributes">
<xsd:attribute name="refresh-check-delay" type="xsd:long">
<xsd:annotation>
<xsd:documentation><![CDATA[
The delay (in milliseconds) between checks for updated sources when
using the refreshable beans feature.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:attributeGroup>
</xsd:schema>

View File

@@ -0,0 +1,13 @@
package example.profilescan;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile(ProfileAnnotatedComponent.PROFILE_NAME)
@Component(ProfileAnnotatedComponent.BEAN_NAME)
public class ProfileAnnotatedComponent {
public static final String BEAN_NAME = "profileAnnotatedComponent";
public static final String PROFILE_NAME = "test";
}

View File

@@ -16,6 +16,7 @@
package org.springframework.context.annotation;
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
/**
@@ -32,7 +33,7 @@ public class AsmCircularImportDetectionTests extends AbstractCircularImportDetec
@Override
protected ConfigurationClassParser newParser() {
return new ConfigurationClassParser(new CachingMetadataReaderFactory(), new FailFastProblemReporter());
return new ConfigurationClassParser(new CachingMetadataReaderFactory(), new FailFastProblemReporter(), new DefaultEnvironment());
}
@Override

View File

@@ -152,11 +152,12 @@ public class ClassPathBeanDefinitionScannerTests {
public void testSimpleScanWithDefaultFiltersAndOverriddenEqualNamedBean() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBeanDefinition("myNamedDao", new RootBeanDefinition(NamedStubDao.class));
int initialBeanCount = context.getBeanDefinitionCount();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
int beanCount = scanner.scan(BASE_PACKAGE);
assertEquals(5, beanCount);
assertEquals(6, context.getBeanDefinitionCount());
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
assertEquals(5, scannedBeanCount);
assertEquals(initialBeanCount + scannedBeanCount, context.getBeanDefinitionCount());
assertTrue(context.containsBean("serviceInvocationCounter"));
assertTrue(context.containsBean("fooServiceImpl"));
assertTrue(context.containsBean("stubFooDao"));
@@ -170,11 +171,12 @@ public class ClassPathBeanDefinitionScannerTests {
RootBeanDefinition bd = new RootBeanDefinition(NamedStubDao.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
context.registerBeanDefinition("myNamedDao", bd);
int initialBeanCount = context.getBeanDefinitionCount();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
int beanCount = scanner.scan(BASE_PACKAGE);
assertEquals(5, beanCount);
assertEquals(6, context.getBeanDefinitionCount());
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
assertEquals(5, scannedBeanCount);
assertEquals(initialBeanCount + scannedBeanCount, context.getBeanDefinitionCount());
assertTrue(context.containsBean("serviceInvocationCounter"));
assertTrue(context.containsBean("fooServiceImpl"));
assertTrue(context.containsBean("stubFooDao"));
@@ -362,11 +364,12 @@ public class ClassPathBeanDefinitionScannerTests {
public void testMultipleScanCalls() {
GenericApplicationContext context = new GenericApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
int beanCount = scanner.scan(BASE_PACKAGE);
assertEquals(10, beanCount);
assertEquals(beanCount, context.getBeanDefinitionCount());
int initialBeanCount = context.getBeanDefinitionCount();
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
assertEquals(10, scannedBeanCount);
assertEquals(scannedBeanCount, context.getBeanDefinitionCount() - initialBeanCount);
int addedBeanCount = scanner.scan("org.springframework.aop.aspectj.annotation");
assertEquals(beanCount + addedBeanCount, context.getBeanDefinitionCount());
assertEquals(initialBeanCount + scannedBeanCount + addedBeanCount, context.getBeanDefinitionCount());
}
@Test

View File

@@ -16,10 +16,30 @@
package org.springframework.context.annotation;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Pattern;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import example.profilescan.ProfileAnnotatedComponent;
import example.scannable.FooDao;
import example.scannable.FooService;
import example.scannable.FooServiceImpl;
@@ -28,18 +48,6 @@ import example.scannable.NamedComponent;
import example.scannable.NamedStubDao;
import example.scannable.ServiceInvocationCounter;
import example.scannable.StubFooDao;
import org.aspectj.lang.annotation.Aspect;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
/**
* @author Mark Fisher
@@ -49,7 +57,7 @@ import org.springframework.stereotype.Service;
public class ClassPathScanningCandidateComponentProviderTests {
private static final String TEST_BASE_PACKAGE = "example.scannable";
//ClassPathScanningCandidateComponentProviderTests.class.getPackage().getName();
private static final String TEST_PROFILE_PACKAGE = "example.profilescan";
@Test
@@ -102,7 +110,6 @@ public class ClassPathScanningCandidateComponentProviderTests {
assertFalse(containsBeanClass(candidates, NamedStubDao.class));
}
@SuppressWarnings("unchecked")
@Test
public void testWithAspectAnnotationOnly() throws Exception {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
@@ -155,6 +162,59 @@ public class ClassPathScanningCandidateComponentProviderTests {
assertFalse(containsBeanClass(candidates, FooServiceImpl.class));
}
@Test
public void testWithNullEnvironment() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_PROFILE_PACKAGE);
assertThat(containsBeanClass(candidates, ProfileAnnotatedComponent.class), is(false));
}
@Test
public void testWithInactiveProfile() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
ConfigurableEnvironment env = new DefaultEnvironment();
env.setActiveProfiles("other");
provider.setEnvironment(env);
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_PROFILE_PACKAGE);
assertThat(containsBeanClass(candidates, ProfileAnnotatedComponent.class), is(false));
}
@Test
public void testWithActiveProfile() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
ConfigurableEnvironment env = new DefaultEnvironment();
env.setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
provider.setEnvironment(env);
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_PROFILE_PACKAGE);
assertThat(containsBeanClass(candidates, ProfileAnnotatedComponent.class), is(true));
}
@Test
public void testIntegrationWithAnnotationConfigApplicationContext_noProfile() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ProfileAnnotatedComponent.class);
ctx.refresh();
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(false));
}
@Test
public void testIntegrationWithAnnotationConfigApplicationContext_validProfile() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
ctx.register(ProfileAnnotatedComponent.class);
ctx.refresh();
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(true));
}
@Test
public void testIntegrationWithAnnotationConfigApplicationContext_invalidProfile() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("other");
ctx.register(ProfileAnnotatedComponent.class);
ctx.refresh();
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(false));
}
private boolean containsBeanClass(Set<BeanDefinition> candidates, Class beanClass) {
for (Iterator it = candidates.iterator(); it.hasNext();) {
ScannedGenericBeanDefinition definition = (ScannedGenericBeanDefinition) it.next();

View File

@@ -0,0 +1,60 @@
/*
* 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.annotation;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan.ExcludeFilter;
import org.springframework.context.annotation.ComponentScan.IncludeFilter;
import org.springframework.core.type.filter.TypeFilter;
/**
* Unit tests for {@link ComponentScan} annotation.
*
* @author Chris Beams
* @since 3.1
*/
public class ComponentScanAnnotationTests {
@Test
public void test() {
}
}
@interface MyAnnotation { }
@Configuration
@ComponentScan(
packageOf={TestBean.class},
nameGenerator = DefaultBeanNameGenerator.class,
scopedProxy = ScopedProxyMode.NO,
scopeResolver = AnnotationScopeMetadataResolver.class,
useDefaultFilters = false,
resourcePattern = "**/*custom.class",
includeFilters = {
@IncludeFilter(type = FilterType.ANNOTATION, value = MyAnnotation.class)
},
excludeFilters = {
@ExcludeFilter(type = FilterType.CUSTOM, value = TypeFilter.class)
}
)
class MyConfig {
}
@ComponentScan(packageOf=example.scannable.NamedComponent.class)
class SimpleConfig { }

View File

@@ -16,7 +16,12 @@
package org.springframework.context.annotation;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -26,11 +31,14 @@ import java.lang.annotation.Target;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import example.profilescan.ProfileAnnotatedComponent;
import example.scannable.AutowiredQualifierFooService;
/**
@@ -88,6 +96,31 @@ public class ComponentScanParserTests {
assertNotNull(testBean.getDependency());
}
@Test
public void testComponentScanRespectsProfileAnnotation() {
String xmlLocation = "org/springframework/context/annotation/componentScanRespectsProfileAnnotationTests.xml";
{ // should exclude the profile-annotated bean if active profiles remains unset
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load(xmlLocation);
context.refresh();
assertThat(context.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(false));
}
{ // should include the profile-annotated bean with active profiles set
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.getEnvironment().setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
context.load(xmlLocation);
context.refresh();
assertThat(context.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(true));
}
{ // ensure the same works for AbstractRefreshableApplicationContext impls too
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext(new String[]{xmlLocation}, false);
context.getEnvironment().setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
context.refresh();
assertThat(context.containsBean(ProfileAnnotatedComponent.BEAN_NAME), is(true));
}
}
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="example.profilescan"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008 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.
@@ -16,23 +16,27 @@
package org.springframework.context.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.PropertyOverrideConfigurer;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.env.MockEnvironment;
/**
* @author Arjen Poutsma
* @author Dave Syer
* @author Chris Beams
* @since 2.5.6
*/
public class ContextNamespaceHandlerTests {
@@ -41,9 +45,9 @@ public class ContextNamespaceHandlerTests {
public void propertyPlaceholder() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-replace.xml", getClass());
Map<String, PropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(PropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceHolderConfigurer found", beans.isEmpty());
Map<String, AbstractPropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(AbstractPropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
String s = (String) applicationContext.getBean("string");
assertEquals("No properties replaced", "bar", s);
}
@@ -56,7 +60,7 @@ public class ContextNamespaceHandlerTests {
"contextNamespaceHandlerTests-system.xml", getClass());
Map<String, PropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(PropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceHolderConfigurer found", beans.isEmpty());
assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
String s = (String) applicationContext.getBean("string");
assertEquals("No properties replaced", "spam", s);
} finally {
@@ -66,13 +70,27 @@ public class ContextNamespaceHandlerTests {
}
}
@Test
public void propertyPlaceholderEnvironmentProperties() throws Exception {
MockEnvironment env = MockEnvironment.withProperty("foo", "spam");
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
applicationContext.setEnvironment(env);
applicationContext.load(new ClassPathResource("contextNamespaceHandlerTests-simple.xml", getClass()));
applicationContext.refresh();
Map<String, AbstractPropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(AbstractPropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
String s = (String) applicationContext.getBean("string");
assertEquals("No properties replaced", "spam", s);
}
@Test
public void propertyPlaceholderLocation() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-location.xml", getClass());
Map<String, PropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(PropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceHolderConfigurer found", beans.isEmpty());
assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
String s = (String) applicationContext.getBean("foo");
assertEquals("No properties replaced", "bar", s);
s = (String) applicationContext.getBean("bar");
@@ -85,9 +103,9 @@ public class ContextNamespaceHandlerTests {
public void propertyPlaceholderIgnored() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-replace-ignore.xml", getClass());
Map<String, PropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(PropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceHolderConfigurer found", beans.isEmpty());
Map<String, AbstractPropertyPlaceholderConfigurer> beans = applicationContext
.getBeansOfType(AbstractPropertyPlaceholderConfigurer.class);
assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
String s = (String) applicationContext.getBean("string");
assertEquals("Properties replaced", "${bar}", s);
}

View File

@@ -240,7 +240,6 @@ public class ApplicationContextExpressionTests {
System.getProperties().remove("country");
System.getProperties().remove("name");
}
System.out.println(sw.getTotalTimeMillis());
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 6000);
}

View File

@@ -0,0 +1,58 @@
/*
* 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.expression;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import java.util.HashMap;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import test.beans.TestBean;
/**
* Integration tests for {@link EnvironmentAccessor}, which is registered with
* SpEL for all {@link AbstractApplicationContext} implementations via
* {@link StandardBeanExpressionResolver}.
*
* @author Chris Beams
*/
public class EnvironmentAccessorIntegrationTests {
@Test
@SuppressWarnings("all")
public void braceAccess() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "#{environment['my.name']}")
.getBeanDefinition());
GenericApplicationContext ctx = new GenericApplicationContext(bf);
ctx.getEnvironment().addPropertySource("testMap", new HashMap() {{ put("my.name", "myBean"); }});
ctx.refresh();
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("myBean"));
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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 static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.mock.env.MockEnvironment;
import test.beans.TestBean;
/**
* Unit tests for {@link EnvironmentAwarePropertyPlaceholderConfigurer}.
*
* @author Chris Beams
* @since 3.1
* @see EnvironmentAwarePropertyPlaceholderConfigurerTests
*/
public class EnvironmentAwarePropertyPlaceholderConfigurerTests {
@Test(expected=IllegalArgumentException.class)
public void environmentNotNull() {
new EnvironmentAwarePropertyPlaceholderConfigurer().postProcessBeanFactory(new DefaultListableBeanFactory());
}
@Test
public void localPropertiesOverrideFalse() {
localPropertiesOverride(false);
}
@Test
public void localPropertiesOverrideTrue() {
localPropertiesOverride(true);
}
private void localPropertiesOverride(boolean override) {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${foo}")
.getBeanDefinition());
EnvironmentAwarePropertyPlaceholderConfigurer ppc = new EnvironmentAwarePropertyPlaceholderConfigurer();
ppc.setLocalOverride(override);
ppc.setProperties(MockEnvironment.withProperty("foo", "local").asProperties());
ppc.setEnvironment(MockEnvironment.withProperty("foo", "enclosing"));
ppc.postProcessBeanFactory(bf);
if (override) {
assertThat(bf.getBean(TestBean.class).getName(), equalTo("local"));
} else {
assertThat(bf.getBean(TestBean.class).getName(), equalTo("enclosing"));
}
}
@Test
public void simpleReplacement() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
MockEnvironment env = new MockEnvironment();
env.setProperty("my.name", "myValue");
EnvironmentAwarePropertyPlaceholderConfigurer ppc =
new EnvironmentAwarePropertyPlaceholderConfigurer();
ppc.setEnvironment(env);
ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue"));
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.mock.env;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* Simple {@link ConfigurableEnvironment} implementation exposing a
* {@link #setProperty(String, String)} and {@link #withProperty(String, String)}
* methods for testing purposes.
*
* @author Chris Beams
* @see MockPropertySource
*/
public class MockEnvironment extends AbstractEnvironment {
private MockPropertySource propertySource = new MockPropertySource();
public MockEnvironment() {
getPropertySources().add(propertySource);
}
public void setProperty(String key, String value) {
propertySource.setProperty(key, value);
}
public static MockEnvironment withProperty(String key, String value) {
MockEnvironment environment = new MockEnvironment();
environment.setProperty(key, value);
return environment;
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.mock.env;
import java.util.Properties;
import org.springframework.core.env.PropertiesPropertySource;
public class MockPropertySource extends PropertiesPropertySource {
public MockPropertySource() {
this(new Properties());
}
private MockPropertySource(Properties properties) {
super("mockProperties", properties);
}
public void setProperty(String key, String value) {
this.source.setProperty(key, value);
}
public static MockPropertySource withProperty(String key, String value) {
Properties properties = new Properties();
properties.setProperty(key, value);
return new MockPropertySource(properties);
}
}

View File

@@ -2,7 +2,7 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:properties id="overrideProps">

View File

@@ -2,7 +2,7 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:properties id="placeholderProps">

View File

@@ -2,7 +2,7 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:properties id="placeholderProps">
@@ -11,7 +11,7 @@
<util:properties id="emptyProps"/>
<context:property-placeholder properties-ref="placeholderProps" order="2"/>
<context:property-placeholder properties-ref="placeholderProps" order="2"/>
<context:property-placeholder properties-ref="emptyProps" order="1" ignore-unresolvable="true"/>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<context:property-placeholder/>
<bean id="string" class="java.lang.String">
<constructor-arg value="${foo}"/>
</bean>
</beans>

View File

@@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:properties id="placeholderProps">