diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt
index b8a2b9b768d..6636c9503e8 100644
--- a/build-spring-framework/resources/changelog.txt
+++ b/build-spring-framework/resources/changelog.txt
@@ -7,6 +7,8 @@ Changes in version 3.1 M2 (2011-??-??)
--------------------------------------
* deprecated AbstractJUnit38SpringContextTests and AbstractTransactionalJUnit38SpringContextTests
+* eliminated @Feature support in favor of @Enable* and framework-provided @Configuration classes
+* introduced @EnableTransactionManagement, @EnableScheduling, and other @Enable* annotations
Changes in version 3.1 M1 (2011-02-11)
diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java
index a21999ff776..ae9888dca4d 100644
--- a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java
+++ b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java
@@ -16,13 +16,12 @@
package org.springframework.aop.config;
+import org.w3c.dom.Element;
+
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
/**
* Utility class for handling registration of auto-proxy creators used internally
@@ -53,41 +52,22 @@ public abstract class AopNamespaceUtils {
private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy";
- /**
- * @deprecated since Spring 3.1 in favor of
- * {@link #registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry, ComponentRegistrar, Object, Boolean, Boolean)}
- */
- @Deprecated
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
- registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
- }
-
- public static void registerAutoProxyCreatorIfNecessary(
- BeanDefinitionRegistry registry, ComponentRegistrar parserContext, Object source, Boolean proxyTargetClass, Boolean exposeProxy) {
-
- BeanDefinition beanDefinition =
- AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry, source);
- useClassProxyingIfNecessary(registry, proxyTargetClass, exposeProxy);
registerComponentIfNecessary(beanDefinition, parserContext);
}
- public static void registerAutoProxyCreatorIfNecessary(
- BeanDefinitionRegistry registry, ComponentRegistrar parserContext, Object source, Boolean proxyTargetClass) {
- registerAutoProxyCreatorIfNecessary(registry, parserContext, source, proxyTargetClass, false);
- }
-
public static void registerAspectJAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
- registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
+ registerComponentIfNecessary(beanDefinition, parserContext);
}
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
@@ -96,7 +76,7 @@ public abstract class AopNamespaceUtils {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
- registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
+ registerComponentIfNecessary(beanDefinition, parserContext);
}
/**
@@ -108,7 +88,7 @@ public abstract class AopNamespaceUtils {
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Object source) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), source);
- registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
+ registerComponentIfNecessary(beanDefinition, parserContext);
}
/**
@@ -121,12 +101,6 @@ public abstract class AopNamespaceUtils {
}
- /**
- * @deprecated since Spring 3.1 in favor of
- * {@link #useClassProxyingIfNecessary(BeanDefinitionRegistry, Boolean, Boolean)}
- * which does not require a parameter of type org.w3c.dom.Element
- */
- @Deprecated
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
@@ -140,20 +114,11 @@ public abstract class AopNamespaceUtils {
}
}
- private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Boolean proxyTargetClass, Boolean exposeProxy) {
- if (proxyTargetClass) {
- AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
- }
- if (exposeProxy) {
- AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
- }
- }
-
- private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ComponentRegistrar componentRegistrar) {
+ private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
BeanComponentDefinition componentDefinition =
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
- componentRegistrar.registerComponent(componentDefinition);
+ parserContext.registerComponent(componentDefinition);
}
}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java
deleted file mode 100644
index 45016231d71..00000000000
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.beans.factory.parsing;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public interface ComponentRegistrar {
-
- String registerWithGeneratedName(BeanDefinition beanDefinition);
-
- void registerBeanComponent(BeanComponentDefinition component);
-
- void registerComponent(ComponentDefinition component);
-
-}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java
deleted file mode 100644
index 36a84706f6a..00000000000
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.beans.factory.parsing;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.xml.ParserContext;
-
-/**
- * TODO SPR-7420: document
- *
Adapter is necessary as opposed to having ParserContext
- * implement ComponentRegistrar directly due to tooling issues.
- * STS may ship with a version of Spring older that 3.1 (when
- * this type was introduced), and will run into
- * IncompatibleClassChangeErrors when it's (3.0.5) ParserContext
- * tries to mix with our (3.1.0) BeanDefinitionParser
- * (and related) infrastructure.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class ComponentRegistrarAdapter implements ComponentRegistrar {
-
- private final ParserContext parserContext;
-
- public ComponentRegistrarAdapter(ParserContext parserContext) {
- this.parserContext = parserContext;
- }
-
- public String registerWithGeneratedName(BeanDefinition beanDefinition) {
- return this.parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
- }
-
- public void registerBeanComponent(BeanComponentDefinition component) {
- this.parserContext.registerBeanComponent(component);
- }
-
- public void registerComponent(ComponentDefinition component) {
- this.parserContext.registerComponent(component);
- }
-
-}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ProblemCollector.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ProblemCollector.java
deleted file mode 100644
index f6f9d5717b7..00000000000
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ProblemCollector.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.beans.factory.parsing;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public interface ProblemCollector {
-
- void error(String message);
-
- void error(String message, Throwable cause);
-
- void reportProblems(ProblemReporter reporter);
-
- boolean hasErrors();
-
-}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/SimpleProblemCollector.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/SimpleProblemCollector.java
deleted file mode 100644
index bb0c9bb12d1..00000000000
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/SimpleProblemCollector.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.beans.factory.parsing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.core.io.DescriptiveResource;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class SimpleProblemCollector implements ProblemCollector {
-
- private Location location = null;
- private List errors = new ArrayList();
-
- public SimpleProblemCollector(Object location) {
- if (location != null) {
- this.location = new Location(new DescriptiveResource(location.toString()));
- }
- }
-
- public void error(String message) {
- this.errors.add(new Problem(message, this.location));
- }
-
- public void error(String message, Throwable cause) {
- this.errors.add(new Problem(message, this.location, null, cause));
- }
-
- public void reportProblems(ProblemReporter reporter) {
- for (Problem error : errors) {
- reporter.error(error);
- }
- }
-
- public boolean hasErrors() {
- return this.errors.size() > 0;
- }
-
-}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParser.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParser.java
index 2f352d9dddf..2c92ecd4775 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParser.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParser.java
@@ -22,7 +22,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
/**
* Interface used by the {@link DefaultBeanDefinitionDocumentReader} to handle custom,
- * top-level (directly under {@code }) tags.
+ * top-level (directly under {@code }) tags.
*
* Implementations are free to turn the metadata in the custom tag into as many
* {@link BeanDefinition BeanDefinitions} as required.
@@ -30,19 +30,10 @@ import org.springframework.beans.factory.config.BeanDefinition;
*
The parser locates a {@link BeanDefinitionParser} from the associated
* {@link NamespaceHandler} for the namespace in which the custom tag resides.
*
- *
Implementations are encouraged to decouple XML parsing from bean registration by
- * parsing element(s) into a {@link org.springframework.context.FeatureSpecification
- * FeatureSpecification} object and subsequently executing that specification.
- * Doing so allows for maximum reuse between XML-based and annotation-based
- * configuration options.
- *
* @author Rob Harrop
* @since 2.0
* @see NamespaceHandler
* @see AbstractBeanDefinitionParser
- * @see org.springframework.beans.factory.xml.BeanDefinitionDecorator
- * @see org.springframework.context.FeatureSpecification
- * @see org.springframework.context.AbstractSpecificationExecutor
*/
public interface BeanDefinitionParser {
@@ -53,12 +44,11 @@ public interface BeanDefinitionParser {
* embedded in the supplied {@link ParserContext}.
*
Implementations must return the primary {@link BeanDefinition} that results
* from the parse if they will ever be used in a nested fashion (for example as
- * an inner tag in a <property/> tag). Implementations may return
- * null if they will not be used in a nested fashion.
+ * an inner tag in a {@code } tag). Implementations may return
+ * {@code null} if they will not be used in a nested fashion.
* @param element the element that is to be parsed into one or more {@link BeanDefinition BeanDefinitions}
* @param parserContext the object encapsulating the current state of the parsing process;
- * provides access to a {@link org.springframework.beans.factory.support.BeanDefinitionRegistry
- * BeanDefinitionRegistry}.
+ * provides access to a {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}
* @return the primary {@link BeanDefinition}
*/
BeanDefinition parse(Element element, ParserContext parserContext);
diff --git a/org.springframework.context/.springBeans b/org.springframework.context/.springBeans
index c36c1e5de08..f55953e36ee 100644
--- a/org.springframework.context/.springBeans
+++ b/org.springframework.context/.springBeans
@@ -1,7 +1,7 @@
1
-
+
@@ -11,7 +11,6 @@
src/test/java/org/springframework/context/annotation/configuration/SecondLevelSubConfig-context.xml
src/test/java/org/springframework/context/annotation/configuration/ImportXmlWithAopNamespace-context.xml
src/test/java/org/springframework/context/annotation/Spr6602Tests-context.xml
- src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests-context.xml
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/BeanMethod.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/BeanMethod.java
index 477d69c5b4f..4b5d762d1d5 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/BeanMethod.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/BeanMethod.java
@@ -16,13 +16,13 @@
package org.springframework.context.annotation;
-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.type.MethodMetadata;
/**
- * Represents a {@link Configuration} class method marked with the {@link Bean} annotation.
+ * Represents a {@link Configuration} class method marked with the
+ * {@link Bean} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
@@ -31,30 +31,13 @@ import org.springframework.core.type.MethodMetadata;
* @see ConfigurationClassParser
* @see ConfigurationClassBeanDefinitionReader
*/
-final class BeanMethod {
-
- private final MethodMetadata metadata;
-
- private final ConfigurationClass configurationClass;
-
+final class BeanMethod extends ConfigurationMethod {
public BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
- this.metadata = metadata;
- this.configurationClass = configurationClass;
- }
-
- public MethodMetadata getMetadata() {
- return this.metadata;
- }
-
- public ConfigurationClass getConfigurationClass() {
- return this.configurationClass;
- }
-
- public Location getResourceLocation() {
- return new Location(this.configurationClass.getResource(), this.metadata);
+ super(metadata, configurationClass);
}
+ @Override
public void validate(ProblemReporter problemReporter) {
if (this.configurationClass.getMetadata().isAnnotated(Configuration.class.getName())) {
if (!getMetadata().isOverridable()) {
@@ -68,13 +51,6 @@ final class BeanMethod {
}
}
- @Override
- public String toString() {
- return String.format("[%s:name=%s,declaringClass=%s]",
- this.getClass().getSimpleName(), this.getMetadata().getMethodName(), this.getMetadata().getDeclaringClassName());
- }
-
-
/**
* {@link Bean} methods must be overridable in order to accommodate CGLIB.
*/
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java
deleted file mode 100644
index 47c1abedaa9..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.util.Map;
-
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * {@link FeatureAnnotationParser} implementation that reads attributes from a
- * {@link ComponentScan @ComponentScan} annotation into a {@link ComponentScanSpec}
- * which can in turn be executed by {@link ComponentScanExecutor}.
- * {@link ComponentScanBeanDefinitionParser} serves the same role for
- * the {@code } XML element.
- *
- * Note that {@link ComponentScanSpec} objects may be directly
- * instantiated and returned from {@link Feature @Feature} methods as an
- * alternative to using the {@link ComponentScan @ComponentScan} annotation.
- *
- * @author Chris Beams
- * @since 3.1
- * @see ComponentScan
- * @see ComponentScanSpec
- * @see ComponentScanExecutor
- * @see ComponentScanBeanDefinitionParser
- * @see ConfigurationClassBeanDefinitionReader
- */
-final class ComponentScanAnnotationParser implements FeatureAnnotationParser {
-
- /**
- * Create and return a new {@link ComponentScanSpec} from the given
- * {@link ComponentScan} annotation metadata.
- * @throws IllegalArgumentException if ComponentScan attributes are not present in metadata
- */
- public ComponentScanSpec process(AnnotationMetadata metadata) {
- Map attribs = metadata.getAnnotationAttributes(ComponentScan.class.getName(), true);
- Assert.notNull(attribs, String.format("@ComponentScan annotation not found " +
- "while parsing metadata for class [%s].", metadata.getClassName()));
-
- ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
- ComponentScanSpec spec = new ComponentScanSpec();
-
- for (String pkg : (String[])attribs.get("value")) {
- spec.addBasePackage(pkg);
- }
- for (String pkg : (String[])attribs.get("basePackages")) {
- spec.addBasePackage(pkg);
- }
- for (String className : (String[])attribs.get("basePackageClasses")) {
- spec.addBasePackage(className.substring(0, className.lastIndexOf('.')));
- }
-
- String resolverAttribute = "scopeResolver";
- if (!((String)attribs.get(resolverAttribute)).equals(((Class>)AnnotationUtils.getDefaultValue(ComponentScan.class, resolverAttribute)).getName())) {
- spec.scopeMetadataResolver((String)attribs.get(resolverAttribute), classLoader);
- }
- String scopedProxyAttribute = "scopedProxy";
- ScopedProxyMode scopedProxyMode = (ScopedProxyMode) attribs.get(scopedProxyAttribute);
- if (scopedProxyMode != ((ScopedProxyMode)AnnotationUtils.getDefaultValue(ComponentScan.class, scopedProxyAttribute))) {
- spec.scopedProxyMode(scopedProxyMode);
- }
-
- for (Filter filter : (Filter[]) attribs.get("includeFilters")) {
- spec.addIncludeFilter(filter.type().toString(), filter.value().getName(), classLoader);
- }
- for (Filter filter : (Filter[]) attribs.get("excludeFilters")) {
- spec.addExcludeFilter(filter.type().toString(), filter.value().getName(), classLoader);
- }
-
- spec.resourcePattern((String)attribs.get("resourcePattern"))
- .useDefaultFilters((Boolean)attribs.get("useDefaultFilters"))
- .beanNameGenerator((String)attribs.get("nameGenerator"), classLoader)
- .source(metadata.getClassName())
- .sourceName(metadata.getClassName());
-
- return spec;
- }
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
index a10f608053f..2f6d1107fdf 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * 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.
@@ -16,60 +16,263 @@
package org.springframework.context.annotation;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.regex.Pattern;
+
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
+import org.springframework.beans.factory.support.BeanNameGenerator;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.beans.factory.xml.XmlReaderContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
+import org.springframework.core.type.filter.AspectJTypeFilter;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+import org.springframework.core.type.filter.RegexPatternTypeFilter;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.util.StringUtils;
+
/**
- * Parser for the {@code } element. Parsed metadata is
- * used to populate and execute a {@link ComponentScanSpec} instance.
+ * Parser for the {@code } element.
*
* @author Mark Fisher
* @author Ramnivas Laddad
* @author Juergen Hoeller
- * @author Chris Beams
* @since 2.5
- * @see ComponentScan
- * @see ComponentScanSpec
- * @see ComponentScanExecutor
*/
-public class ComponentScanBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
- public FeatureSpecification doParse(Element element, ParserContext parserContext) {
- ClassLoader classLoader = parserContext.getReaderContext().getResourceLoader().getClassLoader();
+ private static final String BASE_PACKAGE_ATTRIBUTE = "base-package";
- ComponentScanSpec spec =
- ComponentScanSpec.forDelimitedPackages(element.getAttribute("base-package"))
- .includeAnnotationConfig(element.getAttribute("annotation-config"))
- .useDefaultFilters(element.getAttribute("use-default-filters"))
- .resourcePattern(element.getAttribute("resource-pattern"))
- .beanNameGenerator(element.getAttribute("name-generator"), classLoader)
- .scopeMetadataResolver(element.getAttribute("scope-resolver"), classLoader)
- .scopedProxyMode(element.getAttribute("scoped-proxy"))
- .beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults())
- .autowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
+ private static final String RESOURCE_PATTERN_ATTRIBUTE = "resource-pattern";
+
+ private static final String USE_DEFAULT_FILTERS_ATTRIBUTE = "use-default-filters";
+
+ private static final String ANNOTATION_CONFIG_ATTRIBUTE = "annotation-config";
+
+ private static final String NAME_GENERATOR_ATTRIBUTE = "name-generator";
+
+ private static final String SCOPE_RESOLVER_ATTRIBUTE = "scope-resolver";
+
+ private static final String SCOPED_PROXY_ATTRIBUTE = "scoped-proxy";
+
+ private static final String EXCLUDE_FILTER_ELEMENT = "exclude-filter";
+
+ private static final String INCLUDE_FILTER_ELEMENT = "include-filter";
+
+ private static final String FILTER_TYPE_ATTRIBUTE = "type";
+
+ private static final String FILTER_EXPRESSION_ATTRIBUTE = "expression";
+
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
+ ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
+
+ // Actually scan for bean definitions and register them.
+ ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
+ Set beanDefinitions = scanner.doScan(basePackages);
+ registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
+
+ return null;
+ }
+
+ protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
+ XmlReaderContext readerContext = parserContext.getReaderContext();
+
+ boolean useDefaultFilters = true;
+ if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
+ useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
+ }
+
+ // Delegate bean definition registration to scanner class.
+ ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
+ scanner.setResourceLoader(readerContext.getResourceLoader());
+ scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
+ scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
+
+ if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
+ scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
+ }
+
+ try {
+ parseBeanNameGenerator(element, scanner);
+ }
+ catch (Exception ex) {
+ readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
+ }
+
+ try {
+ parseScope(element, scanner);
+ }
+ catch (Exception ex) {
+ readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
+ }
+
+ parseTypeFilters(element, scanner, readerContext, parserContext);
+
+ return scanner;
+ }
+
+ protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
+ return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters);
+ }
+
+ protected void registerComponents(
+ XmlReaderContext readerContext, Set beanDefinitions, Element element) {
+
+ Object source = readerContext.extractSource(element);
+ CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
+
+ for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
+ compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
+ }
+
+ // Register annotation config processors, if necessary.
+ boolean annotationConfig = true;
+ if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
+ annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
+ }
+ if (annotationConfig) {
+ Set processorDefinitions =
+ AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
+ for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
+ compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
+ }
+ }
+
+ readerContext.fireComponentRegistered(compositeDef);
+ }
+
+ protected void parseBeanNameGenerator(Element element, ClassPathBeanDefinitionScanner scanner) {
+ if (element.hasAttribute(NAME_GENERATOR_ATTRIBUTE)) {
+ BeanNameGenerator beanNameGenerator = (BeanNameGenerator) instantiateUserDefinedStrategy(
+ element.getAttribute(NAME_GENERATOR_ATTRIBUTE), BeanNameGenerator.class,
+ scanner.getResourceLoader().getClassLoader());
+ scanner.setBeanNameGenerator(beanNameGenerator);
+ }
+ }
+
+ protected void parseScope(Element element, ClassPathBeanDefinitionScanner scanner) {
+ // Register ScopeMetadataResolver if class name provided.
+ if (element.hasAttribute(SCOPE_RESOLVER_ATTRIBUTE)) {
+ if (element.hasAttribute(SCOPED_PROXY_ATTRIBUTE)) {
+ throw new IllegalArgumentException(
+ "Cannot define both 'scope-resolver' and 'scoped-proxy' on tag");
+ }
+ ScopeMetadataResolver scopeMetadataResolver = (ScopeMetadataResolver) instantiateUserDefinedStrategy(
+ element.getAttribute(SCOPE_RESOLVER_ATTRIBUTE), ScopeMetadataResolver.class,
+ scanner.getResourceLoader().getClassLoader());
+ scanner.setScopeMetadataResolver(scopeMetadataResolver);
+ }
+
+ if (element.hasAttribute(SCOPED_PROXY_ATTRIBUTE)) {
+ String mode = element.getAttribute(SCOPED_PROXY_ATTRIBUTE);
+ if ("targetClass".equals(mode)) {
+ scanner.setScopedProxyMode(ScopedProxyMode.TARGET_CLASS);
+ }
+ else if ("interfaces".equals(mode)) {
+ scanner.setScopedProxyMode(ScopedProxyMode.INTERFACES);
+ }
+ else if ("no".equals(mode)) {
+ scanner.setScopedProxyMode(ScopedProxyMode.NO);
+ }
+ else {
+ throw new IllegalArgumentException("scoped-proxy only supports 'no', 'interfaces' and 'targetClass'");
+ }
+ }
+ }
+
+ protected void parseTypeFilters(
+ Element element, ClassPathBeanDefinitionScanner scanner, XmlReaderContext readerContext, ParserContext parserContext) {
// Parse exclude and include filter elements.
+ ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
NodeList nodeList = element.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
String localName = parserContext.getDelegate().getLocalName(node);
- String filterType = ((Element)node).getAttribute("type");
- String expression = ((Element)node).getAttribute("expression");
- if ("include-filter".equals(localName)) {
- spec.addIncludeFilter(filterType, expression, classLoader);
+ try {
+ if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
+ TypeFilter typeFilter = createTypeFilter((Element) node, classLoader);
+ scanner.addIncludeFilter(typeFilter);
+ }
+ else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
+ TypeFilter typeFilter = createTypeFilter((Element) node, classLoader);
+ scanner.addExcludeFilter(typeFilter);
+ }
}
- else if ("exclude-filter".equals(localName)) {
- spec.addExcludeFilter(filterType, expression, classLoader);
+ catch (Exception ex) {
+ readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
}
}
}
+ }
- return spec;
+ @SuppressWarnings("unchecked")
+ protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader) {
+ String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
+ String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
+ try {
+ if ("annotation".equals(filterType)) {
+ return new AnnotationTypeFilter((Class) classLoader.loadClass(expression));
+ }
+ else if ("assignable".equals(filterType)) {
+ return new AssignableTypeFilter(classLoader.loadClass(expression));
+ }
+ else if ("aspectj".equals(filterType)) {
+ return new AspectJTypeFilter(expression, classLoader);
+ }
+ else if ("regex".equals(filterType)) {
+ return new RegexPatternTypeFilter(Pattern.compile(expression));
+ }
+ else if ("custom".equals(filterType)) {
+ Class filterClass = classLoader.loadClass(expression);
+ if (!TypeFilter.class.isAssignableFrom(filterClass)) {
+ throw new IllegalArgumentException(
+ "Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
+ }
+ return (TypeFilter) BeanUtils.instantiateClass(filterClass);
+ }
+ else {
+ throw new IllegalArgumentException("Unsupported filter type: " + filterType);
+ }
+ }
+ catch (ClassNotFoundException ex) {
+ throw new FatalBeanException("Type filter class not found: " + expression, ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object instantiateUserDefinedStrategy(String className, Class strategyType, ClassLoader classLoader) {
+ Object result = null;
+ try {
+ result = classLoader.loadClass(className).newInstance();
+ }
+ catch (ClassNotFoundException ex) {
+ throw new IllegalArgumentException("Class [" + className + "] for strategy [" +
+ strategyType.getName() + "] not found", ex);
+ }
+ catch (Exception ex) {
+ throw new IllegalArgumentException("Unable to instantiate class [" + className + "] for strategy [" +
+ strategyType.getName() + "]. A zero-argument constructor is required", ex);
+ }
+
+ if (!strategyType.isAssignableFrom(result.getClass())) {
+ throw new IllegalArgumentException("Provided class name must be an implementation of " + strategyType);
+ }
+ return result;
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanExecutor.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanExecutor.java
deleted file mode 100644
index 8570f00cd88..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanExecutor.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.util.Set;
-
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.type.filter.TypeFilter;
-
-/**
- * Executes the {@link ComponentScanSpec} feature specification.
- *
- * @author Chris Beams
- * @since 3.1
- * @see ComponentScanSpec
- * @see ComponentScanBeanDefinitionParser
- * @see ComponentScan
- */
-final class ComponentScanExecutor extends AbstractSpecificationExecutor {
-
- /**
- * Configure a {@link ClassPathBeanDefinitionScanner} based on the content of
- * the given specification and perform actual scanning and bean definition
- * registration.
- */
- protected void doExecute(ComponentScanSpec spec, SpecificationContext specificationContext) {
- BeanDefinitionRegistry registry = specificationContext.getRegistry();
- ResourceLoader resourceLoader = specificationContext.getResourceLoader();
- Environment environment = specificationContext.getEnvironment();
-
- ClassPathBeanDefinitionScanner scanner = spec.useDefaultFilters() == null ?
- new ClassPathBeanDefinitionScanner(registry) :
- new ClassPathBeanDefinitionScanner(registry, spec.useDefaultFilters());
-
- scanner.setResourceLoader(resourceLoader);
- scanner.setEnvironment(environment);
-
- if (spec.beanDefinitionDefaults() != null) {
- scanner.setBeanDefinitionDefaults(spec.beanDefinitionDefaults());
- }
- if (spec.autowireCandidatePatterns() != null) {
- scanner.setAutowireCandidatePatterns(spec.autowireCandidatePatterns());
- }
-
- if (spec.resourcePattern() != null) {
- scanner.setResourcePattern(spec.resourcePattern());
- }
- if (spec.beanNameGenerator() != null) {
- scanner.setBeanNameGenerator(spec.beanNameGenerator());
- }
- if (spec.includeAnnotationConfig() != null) {
- scanner.setIncludeAnnotationConfig(spec.includeAnnotationConfig());
- }
- if (spec.scopeMetadataResolver() != null) {
- scanner.setScopeMetadataResolver(spec.scopeMetadataResolver());
- }
- if (spec.scopedProxyMode() != null) {
- scanner.setScopedProxyMode(spec.scopedProxyMode());
- }
- for (TypeFilter filter : spec.includeFilters()) {
- scanner.addIncludeFilter(filter);
- }
- for (TypeFilter filter : spec.excludeFilters()) {
- scanner.addExcludeFilter(filter);
- }
-
- Set scannedBeans = scanner.doScan(spec.basePackages());
-
- Object source = spec.source();
- String sourceName = spec.sourceName();
- CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(sourceName, source);
-
- for (BeanDefinitionHolder beanDefHolder : scannedBeans) {
- compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
- }
-
- // Register annotation config processors, if necessary.
- if ((spec.includeAnnotationConfig() != null) && spec.includeAnnotationConfig()) {
- Set processorDefinitions =
- AnnotationConfigUtils.registerAnnotationConfigProcessors(registry, source);
- for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
- compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
- }
- }
-
- specificationContext.getRegistrar().registerComponent(compositeDef);
- }
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanSpec.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanSpec.java
deleted file mode 100644
index 13b757ba95f..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanSpec.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.beans.factory.support.BeanDefinitionDefaults;
-import org.springframework.beans.factory.support.BeanNameGenerator;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.AnnotationTypeFilter;
-import org.springframework.core.type.filter.AspectJTypeFilter;
-import org.springframework.core.type.filter.AssignableTypeFilter;
-import org.springframework.core.type.filter.RegexPatternTypeFilter;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * Specifies the configuration of Spring's component-scanning feature.
- * May be used directly within a {@link Feature @Feature} method, or indirectly
- * through the {@link ComponentScan @ComponentScan} annotation.
- *
- * @author Chris Beams
- * @since 3.1
- * @see ComponentScan
- * @see ComponentScanAnnotationParser
- * @see ComponentScanBeanDefinitionParser
- * @see ComponentScanExecutor
- */
-public final class ComponentScanSpec extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = ComponentScanExecutor.class;
-
- private Boolean includeAnnotationConfig = null;
- private String resourcePattern = null;
- private List basePackages = new ArrayList();
- private Object beanNameGenerator = null;
- private Object scopeMetadataResolver = null;
- private Object scopedProxyMode = null;
- private Boolean useDefaultFilters = null;
- private List includeFilters = new ArrayList();
- private List excludeFilters = new ArrayList();
-
- private BeanDefinitionDefaults beanDefinitionDefaults;
- private String[] autowireCandidatePatterns;
-
- private ClassLoader classLoader;
-
- /**
- * Package-visible constructor for use by {@link ComponentScanBeanDefinitionParser}.
- * End users should always call String... or Class>... constructors to specify
- * base packages.
- *
- * @see #validate()
- */
- ComponentScanSpec() {
- super(EXECUTOR_TYPE);
- }
-
- /**
- *
- * @param basePackages
- * @see #forDelimitedPackages(String)
- */
- public ComponentScanSpec(String... basePackages) {
- this();
- Assert.notEmpty(basePackages, "At least one base package must be specified");
- for (String basePackage : basePackages) {
- addBasePackage(basePackage);
- }
- }
-
- public ComponentScanSpec(Class>... basePackageClasses) {
- this(packagesFor(basePackageClasses));
- }
-
-
- public ComponentScanSpec includeAnnotationConfig(Boolean includeAnnotationConfig) {
- this.includeAnnotationConfig = includeAnnotationConfig;
- return this;
- }
-
- ComponentScanSpec includeAnnotationConfig(String includeAnnotationConfig) {
- if (StringUtils.hasText(includeAnnotationConfig)) {
- this.includeAnnotationConfig = Boolean.valueOf(includeAnnotationConfig);
- }
- return this;
- }
-
- Boolean includeAnnotationConfig() {
- return this.includeAnnotationConfig;
- }
-
- public ComponentScanSpec resourcePattern(String resourcePattern) {
- if (StringUtils.hasText(resourcePattern)) {
- this.resourcePattern = resourcePattern;
- }
- return this;
- }
-
- String resourcePattern() {
- return resourcePattern;
- }
-
- ComponentScanSpec addBasePackage(String basePackage) {
- if (StringUtils.hasText(basePackage)) {
- this.basePackages.add(basePackage);
- }
- return this;
- }
-
- /**
- * Return the set of base packages specified, never {@code null}, never empty
- * post-validation.
- * @see #doValidate(SimpleProblemReporter)
- */
- String[] basePackages() {
- return this.basePackages.toArray(new String[this.basePackages.size()]);
- }
-
- public ComponentScanSpec beanNameGenerator(BeanNameGenerator beanNameGenerator) {
- this.beanNameGenerator = beanNameGenerator;
- return this;
- }
-
- /**
- * Set the class name of the BeanNameGenerator to be used and the ClassLoader
- * to load it.
- */
- ComponentScanSpec beanNameGenerator(String beanNameGenerator, ClassLoader classLoader) {
- setClassLoader(classLoader);
- if (StringUtils.hasText(beanNameGenerator)) {
- this.beanNameGenerator = beanNameGenerator;
- }
- return this;
- }
-
- BeanNameGenerator beanNameGenerator() {
- return nullSafeTypedObject(this.beanNameGenerator, BeanNameGenerator.class);
- }
-
- public ComponentScanSpec scopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
- this.scopeMetadataResolver = scopeMetadataResolver;
- return this;
- }
-
- ComponentScanSpec scopeMetadataResolver(String scopeMetadataResolver, ClassLoader classLoader) {
- setClassLoader(classLoader);
- if (StringUtils.hasText(scopeMetadataResolver)) {
- this.scopeMetadataResolver = scopeMetadataResolver;
- }
- return this;
- }
-
- ScopeMetadataResolver scopeMetadataResolver() {
- return nullSafeTypedObject(this.scopeMetadataResolver, ScopeMetadataResolver.class);
- }
-
- public ComponentScanSpec scopedProxyMode(ScopedProxyMode scopedProxyMode) {
- this.scopedProxyMode = scopedProxyMode;
- return this;
- }
-
- ComponentScanSpec scopedProxyMode(String scopedProxyMode) {
- if (StringUtils.hasText(scopedProxyMode)) {
- this.scopedProxyMode = scopedProxyMode;
- }
- return this;
- }
-
- ScopedProxyMode scopedProxyMode() {
- return nullSafeTypedObject(this.scopedProxyMode, ScopedProxyMode.class);
- }
-
- public ComponentScanSpec useDefaultFilters(Boolean useDefaultFilters) {
- this.useDefaultFilters = useDefaultFilters;
- return this;
- }
-
- ComponentScanSpec useDefaultFilters(String useDefaultFilters) {
- if (StringUtils.hasText(useDefaultFilters)) {
- this.useDefaultFilters = Boolean.valueOf(useDefaultFilters);
- }
- return this;
- }
-
- Boolean useDefaultFilters() {
- return this.useDefaultFilters;
- }
-
- public ComponentScanSpec includeFilters(TypeFilter... includeFilters) {
- this.includeFilters.clear();
- for (TypeFilter filter : includeFilters) {
- addIncludeFilter(filter);
- }
- return this;
- }
-
- ComponentScanSpec addIncludeFilter(TypeFilter includeFilter) {
- Assert.notNull(includeFilter, "includeFilter must not be null");
- this.includeFilters.add(includeFilter);
- return this;
- }
-
- ComponentScanSpec addIncludeFilter(String filterType, String expression, ClassLoader classLoader) {
- this.includeFilters.add(new FilterTypeDescriptor(filterType, expression, classLoader));
- return this;
- }
-
- TypeFilter[] includeFilters() {
- return this.includeFilters.toArray(new TypeFilter[this.includeFilters.size()]);
- }
-
- public ComponentScanSpec excludeFilters(TypeFilter... excludeFilters) {
- this.excludeFilters.clear();
- for (TypeFilter filter : excludeFilters) {
- addExcludeFilter(filter);
- }
- return this;
- }
-
- ComponentScanSpec addExcludeFilter(TypeFilter excludeFilter) {
- Assert.notNull(excludeFilter, "excludeFilter must not be null");
- this.excludeFilters.add(excludeFilter);
- return this;
- }
-
- ComponentScanSpec addExcludeFilter(String filterType, String expression, ClassLoader classLoader) {
- this.excludeFilters.add(new FilterTypeDescriptor(filterType, expression, classLoader));
- return this;
- }
-
- TypeFilter[] excludeFilters() {
- return this.excludeFilters.toArray(new TypeFilter[this.excludeFilters.size()]);
- }
-
- ComponentScanSpec beanDefinitionDefaults(BeanDefinitionDefaults beanDefinitionDefaults) {
- this.beanDefinitionDefaults = beanDefinitionDefaults;
- return this;
- }
-
- BeanDefinitionDefaults beanDefinitionDefaults() {
- return this.beanDefinitionDefaults;
- }
-
- ComponentScanSpec autowireCandidatePatterns(String[] autowireCandidatePatterns) {
- this.autowireCandidatePatterns = autowireCandidatePatterns;
- return this;
- }
-
- String[] autowireCandidatePatterns() {
- return this.autowireCandidatePatterns;
- }
-
-
- /**
- * Create a ComponentScanSpec from a single string containing
- * delimited package names.
- * @see ConfigurableApplicationContext#CONFIG_LOCATION_DELIMITERS
- */
- static ComponentScanSpec forDelimitedPackages(String basePackages) {
- Assert.notNull(basePackages, "base packages must not be null");
- return new ComponentScanSpec(
- StringUtils.tokenizeToStringArray(basePackages,
- ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
-
- public void doValidate(ProblemCollector problems) {
- if(this.basePackages.isEmpty()) {
- problems.error("At least one base package must be specified");
- }
-
- if(this.beanNameGenerator instanceof String) {
- this.beanNameGenerator = instantiateUserDefinedType("bean name generator", BeanNameGenerator.class, this.beanNameGenerator, this.classLoader, problems);
- }
-
- if(this.scopeMetadataResolver instanceof String) {
- this.scopeMetadataResolver = instantiateUserDefinedType("scope metadata resolver", ScopeMetadataResolver.class, this.scopeMetadataResolver, this.classLoader, problems);
- }
-
- if (this.scopedProxyMode instanceof String) {
- if ("targetClass".equalsIgnoreCase((String)this.scopedProxyMode)) {
- this.scopedProxyMode = ScopedProxyMode.TARGET_CLASS;
- }
- else if ("interfaces".equalsIgnoreCase((String)this.scopedProxyMode)) {
- this.scopedProxyMode = ScopedProxyMode.INTERFACES;
- }
- else if ("no".equalsIgnoreCase((String)this.scopedProxyMode)) {
- this.scopedProxyMode = ScopedProxyMode.NO;
- }
- else {
- problems.error("invalid scoped proxy mode [%s] supported modes are " +
- "'no', 'interfaces' and 'targetClass'");
- this.scopedProxyMode = null;
- }
- }
-
- if (this.scopeMetadataResolver != null && this.scopedProxyMode != null) {
- problems.error("Cannot define both scope metadata resolver and scoped proxy mode");
- }
-
- for (int i = 0; i < this.includeFilters.size(); i++) {
- if (this.includeFilters.get(i) instanceof FilterTypeDescriptor) {
- this.includeFilters.set(i, ((FilterTypeDescriptor)this.includeFilters.get(i)).createTypeFilter(problems));
- }
- }
-
- for (int i = 0; i < this.excludeFilters.size(); i++) {
- if (this.excludeFilters.get(i) instanceof FilterTypeDescriptor) {
- this.excludeFilters.set(i, ((FilterTypeDescriptor)this.excludeFilters.get(i)).createTypeFilter(problems));
- }
- }
- }
-
- private static Object instantiateUserDefinedType(String description, Class> targetType, Object className, ClassLoader classLoader, ProblemCollector problems) {
- Assert.isInstanceOf(String.class, className, "userType must be of type String");
- Assert.notNull(classLoader, "classLoader must not be null");
- Assert.notNull(targetType, "targetType must not be null");
- Object instance = null;
- try {
- instance = classLoader.loadClass((String)className).newInstance();
- if (!targetType.isAssignableFrom(instance.getClass())) {
- problems.error(description + " class name must be assignable to " + targetType.getSimpleName());
- instance = null;
- }
- }
- catch (ClassNotFoundException ex) {
- problems.error(String.format(description + " class [%s] not found", className), ex);
- }
- catch (Exception ex) {
- problems.error(String.format("Unable to instantiate %s class [%s] for " +
- "strategy [%s]. Has a no-argument constructor been provided?",
- description, className, targetType.getClass().getSimpleName()), ex);
- }
- return instance;
- }
-
- private void setClassLoader(ClassLoader classLoader) {
- Assert.notNull(classLoader, "classLoader must not be null");
- if (this.classLoader == null) {
- this.classLoader = classLoader;
- }
- else {
- Assert.isTrue(this.classLoader == classLoader, "A classLoader has already been assigned " +
- "and the supplied classLoader is not the same instance. Use the same classLoader " +
- "for all string-based class properties.");
- }
- }
-
- @SuppressWarnings("unchecked")
- private static T nullSafeTypedObject(Object object, Class type) {
- if (object != null) {
- if (!(type.isAssignableFrom(object.getClass()))) {
- throw new IllegalStateException(
- String.format("field must be of type %s but was actually of type %s", type, object.getClass()));
- }
- }
- return (T)object;
- }
-
- private static String[] packagesFor(Class>[] classes) {
- ArrayList packages = new ArrayList();
- for (Class> clazz : classes) {
- packages.add(clazz.getPackage().getName());
- }
- return packages.toArray(new String[packages.size()]);
- }
-
-
- private static class FilterTypeDescriptor {
- private String filterType;
- private String expression;
- private ClassLoader classLoader;
-
- FilterTypeDescriptor(String filterType, String expression, ClassLoader classLoader) {
- Assert.notNull(filterType, "filterType must not be null");
- Assert.notNull(expression, "expression must not be null");
- Assert.notNull(classLoader, "classLoader must not be null");
- this.filterType = filterType;
- this.expression = expression;
- this.classLoader = classLoader;
- }
-
- @SuppressWarnings("unchecked")
- TypeFilter createTypeFilter(ProblemCollector problems) {
- try {
- if ("annotation".equalsIgnoreCase(this.filterType)) {
- return new AnnotationTypeFilter((Class) this.classLoader.loadClass(this.expression));
- }
- else if ("assignable".equalsIgnoreCase(this.filterType)
- || "assignable_type".equalsIgnoreCase(this.filterType)) {
- return new AssignableTypeFilter(this.classLoader.loadClass(this.expression));
- }
- else if ("aspectj".equalsIgnoreCase(this.filterType)) {
- return new AspectJTypeFilter(this.expression, this.classLoader);
- }
- else if ("regex".equalsIgnoreCase(this.filterType)) {
- return new RegexPatternTypeFilter(Pattern.compile(this.expression));
- }
- else if ("custom".equalsIgnoreCase(this.filterType)) {
- Class> filterClass = this.classLoader.loadClass(this.expression);
- if (!TypeFilter.class.isAssignableFrom(filterClass)) {
- problems.error(String.format("custom type filter class [%s] must be assignable to %s",
- this.expression, TypeFilter.class));
- }
- return (TypeFilter) BeanUtils.instantiateClass(filterClass);
- }
- else {
- problems.error(String.format("Unsupported filter type [%s]; supported types are: " +
- "'annotation', 'assignable[_type]', 'aspectj', 'regex', 'custom'", this.filterType));
- }
- } catch (ClassNotFoundException ex) {
- problems.error("Type filter class not found: " + this.expression, ex);
- } catch (Exception ex) {
- problems.error(ex.getMessage(), ex.getCause());
- }
-
- return new PlaceholderTypeFilter();
- }
-
-
- private class PlaceholderTypeFilter implements TypeFilter {
-
- public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
- throws IOException {
- throw new UnsupportedOperationException(
- String.format("match() method for placeholder type filter for " +
- "{filterType=%s,expression=%s} should never be invoked",
- filterType, expression));
- }
-
- }
- }
-
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
index 88dc2778f6c..06e16297ade 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
@@ -33,7 +33,6 @@ import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
@@ -45,8 +44,8 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.context.config.SpecificationContext;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.Conventions;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
@@ -94,7 +93,7 @@ public class ConfigurationClassBeanDefinitionReader {
private ResourceLoader resourceLoader;
- private SpecificationContext specificationContext;
+ private Environment environment;
/**
* Create a new {@link ConfigurationClassBeanDefinitionReader} instance that will be used
@@ -111,13 +110,7 @@ public class ConfigurationClassBeanDefinitionReader {
this.problemReporter = problemReporter;
this.metadataReaderFactory = metadataReaderFactory;
this.resourceLoader = resourceLoader;
- // TODO SPR-7420: see about passing in the SpecificationContext created in ConfigurationClassPostProcessor
- this.specificationContext = new SpecificationContext();
- this.specificationContext.setRegistry(this.registry);
- this.specificationContext.setRegistrar(new SimpleComponentRegistrar(this.registry));
- this.specificationContext.setResourceLoader(this.resourceLoader);
- this.specificationContext.setEnvironment(environment);
- this.specificationContext.setProblemReporter(problemReporter);
+ this.environment = environment;
}
@@ -137,7 +130,6 @@ public class ConfigurationClassBeanDefinitionReader {
*/
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
- processFeatureAnnotations(metadata);
doLoadBeanDefinitionForConfigurationClassIfNecessary(configClass);
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
@@ -145,27 +137,6 @@ public class ConfigurationClassBeanDefinitionReader {
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
}
- private void processFeatureAnnotations(AnnotationMetadata metadata) {
- try {
- for (String annotationType : metadata.getAnnotationTypes()) {
- MetadataReader metadataReader = new SimpleMetadataReaderFactory().getMetadataReader(annotationType);
- if (metadataReader.getAnnotationMetadata().isAnnotated(FeatureAnnotation.class.getName())) {
- Map annotationAttributes = metadataReader.getAnnotationMetadata().getAnnotationAttributes(FeatureAnnotation.class.getName(), true);
- // TODO SPR-7420: this is where we can catch user-defined types and avoid instantiating them for STS purposes
- FeatureAnnotationParser processor = (FeatureAnnotationParser) BeanUtils.instantiateClass(Class.forName((String)annotationAttributes.get("parser")));
- FeatureSpecification spec = processor.process(metadata);
- spec.execute(this.specificationContext);
- }
- }
- } catch (BeanDefinitionParsingException ex) {
- throw ex;
- }
- catch (Exception ex) {
- // TODO SPR-7420: what exception to throw?
- throw new RuntimeException(ex);
- }
- }
-
/**
* Register the {@link Configuration} class itself as a bean definition.
*/
@@ -200,7 +171,7 @@ public class ConfigurationClassBeanDefinitionReader {
}
/**
- * Read a particular {@link BeanMethod}, registering bean definitions
+ * Read the given {@link BeanMethod}, registering bean definitions
* with the BeanDefinitionRegistry based on its contents.
*/
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
@@ -423,8 +394,8 @@ public class ConfigurationClassBeanDefinitionReader {
*/
private static class InvalidConfigurationImportProblem extends Problem {
public InvalidConfigurationImportProblem(String className, Resource resource, AnnotationMetadata metadata) {
- super(String.format("%s was @Import'ed but is not annotated with @FeatureConfiguration or " +
- "@Configuration nor does it declare any @Bean methods. Update the class to " +
+ super(String.format("%s was @Import'ed but is not annotated with @Configuration " +
+ "nor does it declare any @Bean methods. Update the class to " +
"meet one of these requirements or do not attempt to @Import it.", className),
new Location(resource, metadata));
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java
index 9e0e546b585..2e4bc37de9b 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java
@@ -197,15 +197,12 @@ class ConfigurationClassEnhancer {
* Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
* existence of this bean object.
*
- * @throws ProxyCreationException if an early bean reference proxy should be
- * created but the return type of the bean method being intercepted is not an
- * interface and thus not a candidate for JDK proxy creation.
* @throws Throwable as a catch-all for any exception that may be thrown when
* invoking the super implementation of the proxied method i.e., the actual
* {@code @Bean} method.
*/
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
- MethodProxy cglibMethodProxy) throws ProxyCreationException, Throwable {
+ MethodProxy cglibMethodProxy) throws Throwable {
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
index 1c821f5ff66..01cbd8ee40a 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
@@ -16,15 +16,9 @@
package org.springframework.context.annotation;
-import static java.lang.String.format;
-
import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,12 +26,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanDefinitionStoreException;
-import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
import org.springframework.beans.factory.parsing.PassThroughSourceExtractor;
import org.springframework.beans.factory.parsing.ProblemReporter;
@@ -47,23 +39,14 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.context.config.SourceAwareSpecification;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
-import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
-import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
/**
* {@link BeanFactoryPostProcessor} used for bootstrapping processing of
@@ -194,175 +177,13 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
/**
- * Find and process all @Configuration classes with @Feature methods in the given registry.
+ * Find and process all @Configuration classes in the given registry.
*/
private void processConfigurationClasses(BeanDefinitionRegistry registry) {
ConfigurationClassBeanDefinitionReader reader = getConfigurationClassBeanDefinitionReader(registry);
- processConfigBeanDefinitions(registry, reader);
+ ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment);
+ processConfigBeanDefinitions(parser, reader, registry);
enhanceConfigurationClasses((ConfigurableListableBeanFactory)registry);
- processFeatureConfigurationClasses((ConfigurableListableBeanFactory) registry);
- }
-
- /**
- * Process any @FeatureConfiguration classes
- */
- private void processFeatureConfigurationClasses(final ConfigurableListableBeanFactory beanFactory) {
- Map featureConfigBeans = retrieveFeatureConfigurationBeans(beanFactory);
-
- if (featureConfigBeans.size() == 0) {
- return;
- }
-
- for (final Object featureConfigBean : featureConfigBeans.values()) {
- checkForBeanMethods(featureConfigBean.getClass());
- }
-
- if (!cglibAvailable) {
- throw new IllegalStateException("CGLIB is required to process @FeatureConfiguration classes. " +
- "Either add CGLIB to the classpath or remove the following @FeatureConfiguration bean definitions: " +
- featureConfigBeans.keySet());
- }
-
- final EarlyBeanReferenceProxyCreator proxyCreator = new EarlyBeanReferenceProxyCreator(beanFactory);
- final SpecificationContext specificationContext = createSpecificationContext(beanFactory);
-
- for (final Object featureConfigBean : featureConfigBeans.values()) {
- ReflectionUtils.doWithMethods(featureConfigBean.getClass(),
- new ReflectionUtils.MethodCallback() {
- public void doWith(Method featureMethod) throws IllegalArgumentException, IllegalAccessException {
- processFeatureMethod(featureMethod, featureConfigBean, specificationContext, proxyCreator);
- } },
- new ReflectionUtils.MethodFilter() {
- public boolean matches(Method candidateMethod) {
- return candidateMethod.isAnnotationPresent(Feature.class);
- } });
- }
- }
-
- /**
- * Alternative to {@link ListableBeanFactory#getBeansWithAnnotation(Class)} that avoids
- * instantiating FactoryBean objects. FeatureConfiguration types cannot be registered as
- * FactoryBeans, so ignoring them won't cause a problem. On the other hand, using gBWA()
- * at this early phase of the container would cause all @Bean methods to be invoked, as they
- * are ultimately FactoryBeans underneath.
- */
- private Map retrieveFeatureConfigurationBeans(ConfigurableListableBeanFactory beanFactory) {
- Map fcBeans = new HashMap();
- for (String beanName : beanFactory.getBeanDefinitionNames()) {
- BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
- if (isFeatureConfiguration(beanDef)) {
- fcBeans.put(beanName, beanFactory.getBean(beanName));
- }
- }
- return fcBeans;
- }
-
- private boolean isFeatureConfiguration(BeanDefinition candidate) {
- if (!(candidate instanceof AbstractBeanDefinition) || (candidate.getBeanClassName() == null)) {
- return false;
- }
- AbstractBeanDefinition beanDef = (AbstractBeanDefinition) candidate;
- if (beanDef.hasBeanClass()) {
- Class> beanClass = beanDef.getBeanClass();
- if (AnnotationUtils.findAnnotation(beanClass, FeatureConfiguration.class) != null) {
- return true;
- }
- }
- else {
- // in the case of @FeatureConfiguration classes included with @Import the bean class name
- // will still be in String form. Since we don't know whether the current bean definition
- // is a @FeatureConfiguration or not, carefully check for the annotation using ASM instead
- // eager classloading.
- String className = null;
- try {
- className = beanDef.getBeanClassName();
- MetadataReader metadataReader = new SimpleMetadataReaderFactory().getMetadataReader(className);
- AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
- if (annotationMetadata.isAnnotated(FeatureConfiguration.class.getName())) {
- return true;
- }
- }
- catch (IOException ex) {
- throw new IllegalStateException("Could not create MetadataReader for class " + className, ex);
- }
- }
- return false;
- }
-
- private void checkForBeanMethods(final Class> featureConfigClass) {
- ReflectionUtils.doWithMethods(featureConfigClass,
- new ReflectionUtils.MethodCallback() {
- public void doWith(Method beanMethod) throws IllegalArgumentException, IllegalAccessException {
- throw new FeatureMethodExecutionException(
- format("@FeatureConfiguration classes must not contain @Bean-annotated methods. " +
- "%s.%s() is annotated with @Bean and must be removed in order to proceed. " +
- "Consider moving this method into a dedicated @Configuration class and " +
- "injecting the bean as a parameter into any @Feature method(s) that need it.",
- beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
- } },
- new ReflectionUtils.MethodFilter() {
- public boolean matches(Method candidateMethod) {
- return BeanAnnotationHelper.isBeanAnnotated(candidateMethod);
- } });
- }
-
- /**
- * TODO SPR-7420: this method invokes user-supplied code, which is not going to fly for STS
- *
- * consider introducing some kind of check to see if we're in a tooling context and make guesses
- * based on return type rather than actually invoking the method and processing the the specification
- * object that returns.
- * @param beanFactory
- * @throws SecurityException
- */
- private void processFeatureMethod(final Method featureMethod, Object configInstance,
- SpecificationContext specificationContext, EarlyBeanReferenceProxyCreator proxyCreator) {
- try {
- // get the return type
- if (!(FeatureSpecification.class.isAssignableFrom(featureMethod.getReturnType()))) {
- // TODO SPR-7420: raise a Problem instead?
- throw new IllegalArgumentException(
- format("Return type for @Feature method %s.%s() must be assignable to FeatureSpecification",
- featureMethod.getDeclaringClass().getSimpleName(), featureMethod.getName()));
- }
-
- List beanArgs = new ArrayList();
- Class>[] parameterTypes = featureMethod.getParameterTypes();
- for (int i = 0; i < parameterTypes.length; i++) {
- MethodParameter mp = new MethodParameter(featureMethod, i);
- DependencyDescriptor dd = new DependencyDescriptor(mp, true, false);
- Object proxiedBean = proxyCreator.createProxyIfPossible(dd);
- beanArgs.add(proxiedBean);
- }
-
- // reflectively invoke that method
- FeatureSpecification spec;
- featureMethod.setAccessible(true);
- spec = (FeatureSpecification) featureMethod.invoke(configInstance, beanArgs.toArray(new Object[beanArgs.size()]));
-
- Assert.notNull(spec,
- format("The specification returned from @Feature method %s.%s() must not be null",
- featureMethod.getDeclaringClass().getSimpleName(), featureMethod.getName()));
-
- if (spec instanceof SourceAwareSpecification) {
- ((SourceAwareSpecification)spec).source(featureMethod);
- ((SourceAwareSpecification)spec).sourceName(featureMethod.getName());
- }
- spec.execute(specificationContext);
- } catch (Exception ex) {
- throw new FeatureMethodExecutionException(ex);
- }
- }
-
- private SpecificationContext createSpecificationContext(ConfigurableListableBeanFactory beanFactory) {
- final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
- SpecificationContext specificationContext = new SpecificationContext();
- specificationContext.setEnvironment(this.environment);
- specificationContext.setResourceLoader(this.resourceLoader);
- specificationContext.setRegistry(registry);
- specificationContext.setRegistrar(new SimpleComponentRegistrar(registry));
- specificationContext.setProblemReporter(this.problemReporter);
- return specificationContext;
}
private ConfigurationClassBeanDefinitionReader getConfigurationClassBeanDefinitionReader(BeanDefinitionRegistry registry) {
@@ -377,7 +198,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* Build and validate a configuration model based on the registry of
* {@link Configuration} classes.
*/
- public void processConfigBeanDefinitions(BeanDefinitionRegistry registry, ConfigurationClassBeanDefinitionReader reader) {
+ public void processConfigBeanDefinitions(ConfigurationClassParser parser, ConfigurationClassBeanDefinitionReader reader, BeanDefinitionRegistry registry) {
Set configCandidates = new LinkedHashSet();
for (String beanName : registry.getBeanDefinitionNames()) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
@@ -391,8 +212,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
return;
}
- // Populate a new configuration model by parsing each @Configuration classes
- ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment);
+ // Parse each @Configuration class
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationMethod.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationMethod.java
new file mode 100644
index 00000000000..624be36d0dc
--- /dev/null
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationMethod.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.context.annotation;
+
+import org.springframework.beans.factory.parsing.Location;
+import org.springframework.beans.factory.parsing.ProblemReporter;
+import org.springframework.core.type.MethodMetadata;
+
+/**
+ * @author Chris Beams
+ * @since 3.1
+ */
+abstract class ConfigurationMethod {
+
+ protected final MethodMetadata metadata;
+
+ protected final ConfigurationClass configurationClass;
+
+
+ public ConfigurationMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
+ this.metadata = metadata;
+ this.configurationClass = configurationClass;
+ }
+
+ public MethodMetadata getMetadata() {
+ return this.metadata;
+ }
+
+ public ConfigurationClass getConfigurationClass() {
+ return this.configurationClass;
+ }
+
+ public Location getResourceLocation() {
+ return new Location(this.configurationClass.getResource(), this.metadata);
+ }
+
+ public void validate(ProblemReporter problemReporter) {
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%s:name=%s,declaringClass=%s]",
+ this.getClass().getSimpleName(), this.getMetadata().getMethodName(), this.getMetadata().getDeclaringClassName());
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxy.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxy.java
deleted file mode 100644
index c0cd0965496..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxy.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-/**
- * Marker interface indicating that an object is a proxy for a bean referenced
- * from within a {@link Feature @Feature} method.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public interface EarlyBeanReferenceProxy {
-
- Object dereferenceTargetBean();
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreator.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreator.java
deleted file mode 100644
index e7480a2de30..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreator.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.beans.factory.config.DependencyDescriptor;
-import org.springframework.util.Assert;
-import org.springframework.util.ReflectionUtils;
-
-/**
- * Creates proxies for beans referenced from within @Feature methods.
- *
- * TODO SPR-7420: document
- * - discuss why proxies are important (avoiding side effects of early instantiation)
- * - discuss benefits of interface-based proxies over concrete proxies
- * - make it clear that both of the above are possible
- * - discuss invocation of @Bean methods and how they too return proxies.
- * this 'proxy returning a proxy' approach can be confusing at first, but the
- * implementation should help in making it clear.
- *
- * @author Chris Beams
- * @since 3.1
- */
-class EarlyBeanReferenceProxyCreator {
-
- static final String MISSING_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE =
- "Cannot create subclass proxy for bean type %s because it does not have a no-arg constructor. " +
- "Add a no-arg constructor or attempt to inject the bean by interface rather than by concrete class.";
-
- static final String PRIVATE_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE =
- "Cannot create subclass proxy for bean type %s because its no-arg constructor is private. " +
- "Increase the visibility of the no-arg constructor or attempt to inject the bean by interface rather " +
- "than by concrete class.";
-
- private final AutowireCapableBeanFactory beanFactory;
-
-
- /**
- * Create a new proxy creator that will dereference proxy target beans against
- * the given bean factory.
- */
- public EarlyBeanReferenceProxyCreator(AutowireCapableBeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- }
-
- /**
- * Create a proxy that will ultimately dereference its target object using
- * the given dependency descriptor. No proxy is created if the dependency type
- * is final, rather the dependency is resolved immediately. This is important
- * especially with regard to supporting @Value injection.
- */
- public Object createProxyIfPossible(DependencyDescriptor descriptor) {
- if (Modifier.isFinal(descriptor.getDependencyType().getModifiers())) {
- return beanFactory.resolveDependency(descriptor, "");
- }
- return doCreateProxy(new ResolveDependencyTargetBeanDereferencingInterceptor(descriptor));
- }
-
- /**
- * Create a proxy that looks up target beans using the given dereferencing interceptor.
- *
- * @see EarlyBeanReferenceProxy#dereferenceTargetBean()
- */
- private Object doCreateProxy(TargetBeanDereferencingInterceptor targetBeanDereferencingInterceptor) {
- Enhancer enhancer = new Enhancer();
- Class> targetBeanType = targetBeanDereferencingInterceptor.getTargetBeanType();
- if (targetBeanType.isInterface()) {
- enhancer.setSuperclass(Object.class);
- enhancer.setInterfaces(new Class>[] {targetBeanType, EarlyBeanReferenceProxy.class});
- } else {
- assertClassIsProxyCapable(targetBeanType);
- enhancer.setSuperclass(targetBeanType);
- enhancer.setInterfaces(new Class>[] {EarlyBeanReferenceProxy.class});
- }
- enhancer.setCallbacks(new Callback[] {
- new BeanMethodInterceptor(),
- new ObjectMethodsInterceptor(),
- targetBeanDereferencingInterceptor,
- new TargetBeanDelegatingMethodInterceptor()
- });
- enhancer.setCallbackFilter(new CallbackFilter() {
- public int accept(Method method) {
- if (BeanAnnotationHelper.isBeanAnnotated(method)) {
- return 0;
- }
- if (ReflectionUtils.isObjectMethod(method)) {
- return 1;
- }
- if (method.getName().equals("dereferenceTargetBean")) {
- return 2;
- }
- return 3;
- }
- });
- return enhancer.create();
- }
-
- /**
- * Return whether the given class is capable of being subclass proxied by CGLIB.
- */
- private static void assertClassIsProxyCapable(Class> clazz) {
- Assert.isTrue(!clazz.isInterface(), "class parameter must be a concrete type");
- try {
- // attempt to retrieve the no-arg constructor for the class
- Constructor> noArgCtor = clazz.getDeclaredConstructor();
- if ((noArgCtor.getModifiers() & Modifier.PRIVATE) != 0) {
- throw new ProxyCreationException(String.format(PRIVATE_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE, clazz.getName()));
- }
- } catch (NoSuchMethodException ex) {
- throw new ProxyCreationException(String.format(MISSING_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE, clazz.getName()));
- }
- }
-
-
- /**
- * Interceptor for @Bean-annotated methods called from early-proxied bean instances, such as
- * @Configuration class instances. Invoking instance methods on early-proxied beans usually
- * causes an eager bean lookup, but in the case of @Bean methods, it is important to return
- * a proxy.
- */
- private class BeanMethodInterceptor implements MethodInterceptor {
-
- public Object intercept(Object obj, final Method beanMethod, Object[] args, MethodProxy proxy) throws Throwable {
- return doCreateProxy(new ByNameLookupTargetBeanDereferencingInterceptor(beanMethod));
- }
-
- }
-
-
- /**
- * Interceptor for methods declared by java.lang.Object()
- */
- private static class ObjectMethodsInterceptor implements MethodInterceptor {
-
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- if (method.getName().equals("toString")) {
- return String.format("EarlyBeanReferenceProxy for bean of type %s",
- obj.getClass().getSuperclass().getSimpleName());
- }
- if (method.getName().equals("hashCode")) {
- return System.identityHashCode(obj);
- }
- if (method.getName().equals("equals")) {
- return obj == args[0];
- }
- if (method.getName().equals("finalize")) {
- return null;
- }
- return proxy.invokeSuper(obj, args);
- }
-
- }
-
-
- /**
- * Strategy interface allowing for various approaches to dereferencing (i.e. 'looking up')
- * the target bean for an early bean reference proxy.
- *
- * @see EarlyBeanReferenceProxy#dereferenceTargetBean()
- */
- private interface TargetBeanDereferencingInterceptor extends MethodInterceptor {
- Class> getTargetBeanType();
- }
-
-
- /**
- * Interceptor that dereferences the target bean for the proxy by calling
- * {@link AutowireCapableBeanFactory#resolveDependency(DependencyDescriptor, String)}.
- *
- * @see EarlyBeanReferenceProxy#dereferenceTargetBean()
- */
- private class ResolveDependencyTargetBeanDereferencingInterceptor implements TargetBeanDereferencingInterceptor {
-
- private final DependencyDescriptor descriptor;
-
- public ResolveDependencyTargetBeanDereferencingInterceptor(DependencyDescriptor descriptor) {
- this.descriptor = descriptor;
- }
-
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- return beanFactory.resolveDependency(descriptor, null);
- }
-
- public Class> getTargetBeanType() {
- return this.descriptor.getDependencyType();
- }
-
- }
-
-
- /**
- * Interceptor that dereferences the target bean for the proxy by calling BeanFactory#getBean(String).
- *
- * @see EarlyBeanReferenceProxy#dereferenceTargetBean()
- */
- private class ByNameLookupTargetBeanDereferencingInterceptor implements TargetBeanDereferencingInterceptor {
-
- private final Method beanMethod;
-
- public ByNameLookupTargetBeanDereferencingInterceptor(Method beanMethod) {
- this.beanMethod = beanMethod;
- }
-
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- return beanFactory.getBean(BeanAnnotationHelper.determineBeanNameFor(beanMethod));
- }
-
- public Class> getTargetBeanType() {
- return beanMethod.getReturnType();
- }
-
- }
-
-
- /**
- * Interceptor that dereferences the target bean for the proxy and delegates the
- * current method call to it.
- * @see TargetBeanDereferencingInterceptor
- */
- private static class TargetBeanDelegatingMethodInterceptor implements MethodInterceptor {
-
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- Object targetBean = ((EarlyBeanReferenceProxy)obj).dereferenceTargetBean();
- return method.invoke(targetBean, args);
- }
-
- }
-
-}
-
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/Feature.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/Feature.java
deleted file mode 100644
index dc54a0e94d7..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/Feature.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Feature {
-
-}
\ No newline at end of file
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotation.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotation.java
deleted file mode 100644
index 20bb2802ba0..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotation.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Meta-annotation indicating that an annotation should be processed
- * to produce a {@code FeatureSpecification}.
- *
- * See {@link ComponentScan @ComponentScan} for an implementation example.
- *
- * @author Chris Beams
- * @since 3.1
- * @see ComponentScan
- * @see org.springframework.context.config.FeatureSpecification
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.ANNOTATION_TYPE)
-public @interface FeatureAnnotation {
-
- /**
- * Indicate the class that should be used to parse this annotation
- * into a {@code FeatureSpecification}.
- */
- Class extends FeatureAnnotationParser> parser();
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotationParser.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotationParser.java
deleted file mode 100644
index 65a402de417..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureAnnotationParser.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.core.type.AnnotationMetadata;
-
-/**
- * Interface for parsing {@link AnnotationMetadata} from a {@link FeatureAnnotation}
- * into a {@link FeatureSpecification} object. Used in conjunction with a
- * {@link FeatureSpecificationExecutor} to provide a source-agnostic approach to
- * handling configuration metadata.
- *
- *
For example, Spring's component-scanning can be configured via XML using
- * the {@code context:component-scan} element or via the {@link ComponentScan}
- * annotation. In either case, the metadata is the same -- only the source
- * format differs. {@link ComponentScanBeanDefinitionParser} is used to create
- * a specification from the {@code } XML element, while
- * {@link ComponentScanAnnotationParser} creates a specification from the
- * the annotation style. They both produce a {@link ComponentScanSpec}
- * object that is ultimately delegated to a {@link ComponentScanExecutor}
- * which understands how to configure a {@link ClassPathBeanDefinitionScanner},
- * perform actual scanning, and register actual bean definitions against the
- * container.
- *
- * Implementations must be instantiable via a no-arg constructor.
- *
- * TODO SPR-7420: documentation (clean up)
- * TODO SPR-7420: rework so annotations declare their creator.
- *
- *
- * @author Chris Beams
- * @since 3.1
- * @see FeatureAnnotation#parser()
- * @see FeatureSpecification
- * @see FeatureSpecificationExecutor
- */
-public interface FeatureAnnotationParser {
-
- /**
- * Parse the given annotation metadata and populate a {@link FeatureSpecification}
- * object suitable for execution by a {@link FeatureSpecificationExecutor}.
- */
- FeatureSpecification process(AnnotationMetadata metadata);
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureConfiguration.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureConfiguration.java
deleted file mode 100644
index 6fbfbf2b98b..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureConfiguration.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.stereotype.Component;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- * @see Configuration
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Component
-public @interface FeatureConfiguration {
-
- /**
- * Explicitly specify the name of the Spring bean definition associated
- * with this FeatureConfiguration class. If left unspecified (the common case),
- * a bean name will be automatically generated.
- *
- *
The custom name applies only if the FeatureConfiguration class is picked up via
- * component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.
- * If the FeatureConfiguration class is registered as a traditional XML bean definition,
- * the name/id of the bean element will take precedence.
- *
- * @return the specified bean name, if any
- * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
- */
- String value() default "";
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureMethodExecutionException.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureMethodExecutionException.java
deleted file mode 100644
index e5aa6f54365..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/FeatureMethodExecutionException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-@SuppressWarnings("serial")
-class FeatureMethodExecutionException extends RuntimeException {
- public FeatureMethodExecutionException(Throwable cause) {
- super(cause);
- }
-
- public FeatureMethodExecutionException(String message) {
- super(message);
- }
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ProxyCreationException.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ProxyCreationException.java
deleted file mode 100644
index f85f311f83e..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ProxyCreationException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-@SuppressWarnings("serial")
-class ProxyCreationException extends RuntimeException {
-
- public ProxyCreationException(String message) {
- super(message);
- }
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java
deleted file mode 100644
index d812f2983c0..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-class SimpleComponentRegistrar implements ComponentRegistrar {
-
- private final BeanDefinitionRegistry registry;
-
- public SimpleComponentRegistrar(BeanDefinitionRegistry registry) {
- this.registry = registry;
- }
-
- public String registerWithGeneratedName(BeanDefinition beanDefinition) {
- return BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, this.registry);
- }
-
- public void registerBeanComponent(BeanComponentDefinition component) {
- BeanDefinitionReaderUtils.registerBeanDefinition(component, this.registry);
- registerComponent(component);
- }
-
- public void registerComponent(ComponentDefinition component) {
- // no-op
- }
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractFeatureSpecification.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractFeatureSpecification.java
deleted file mode 100644
index 0fde6301a2e..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractFeatureSpecification.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.beans.factory.parsing.ProblemReporter;
-import org.springframework.beans.factory.parsing.SimpleProblemCollector;
-
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public abstract class AbstractFeatureSpecification implements SourceAwareSpecification {
-
- private static final Object DUMMY_SOURCE = new Object();
- private static final String DUMMY_SOURCE_NAME = "dummySource";
-
- protected Class extends FeatureSpecificationExecutor> executorType;
-
- private Object source = DUMMY_SOURCE;
- private String sourceName = DUMMY_SOURCE_NAME;
-
- protected AbstractFeatureSpecification(Class extends FeatureSpecificationExecutor> executorType) {
- this.executorType = executorType;
- }
-
- public final boolean validate(ProblemReporter problemReporter) {
- ProblemCollector collector = new SimpleProblemCollector(this.source());
- this.doValidate(collector);
- collector.reportProblems(problemReporter);
- return collector.hasErrors() ? false : true;
- }
-
- protected abstract void doValidate(ProblemCollector problems);
-
- public AbstractFeatureSpecification source(Object source) {
- this.source = source;
- return this;
- }
-
- public Object source() {
- return this.source;
- }
-
- public AbstractFeatureSpecification sourceName(String sourceName) {
- this.sourceName = sourceName;
- return this;
- }
-
- public String sourceName() {
- return this.sourceName;
- }
-
- public void execute(SpecificationContext specificationContext) {
- FeatureSpecificationExecutor executor =
- BeanUtils.instantiateClass(this.executorType);
- executor.execute(this, specificationContext);
- }
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java
deleted file mode 100644
index 58472b55142..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-import java.lang.reflect.Field;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
-import org.springframework.beans.factory.parsing.ProblemReporter;
-import org.springframework.beans.factory.parsing.ReaderContext;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.core.env.DefaultEnvironment;
-import org.w3c.dom.Element;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public abstract class AbstractSpecificationBeanDefinitionParser implements BeanDefinitionParser {
-
- public final BeanDefinition parse(Element element, ParserContext parserContext) {
- FeatureSpecification spec = doParse(element, parserContext);
- if (spec instanceof SourceAwareSpecification) {
- ((SourceAwareSpecification)spec).source(parserContext.getReaderContext().extractSource(element));
- ((SourceAwareSpecification)spec).sourceName(element.getTagName());
- }
- spec.execute(specificationContextFrom(parserContext));
- return null;
- }
-
- abstract protected FeatureSpecification doParse(Element element, ParserContext parserContext);
-
- /**
- * Adapt the given ParserContext into a SpecificationContext.
- */
- private SpecificationContext specificationContextFrom(ParserContext parserContext) {
- SpecificationContext specContext = new SpecificationContext();
- specContext.setRegistry(parserContext.getRegistry());
- specContext.setRegistrar(new ComponentRegistrarAdapter(parserContext));
- specContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
- try {
- // again, STS constraints around the addition of the new getEnvironment()
- // method in 3.1.0 (it's not present in STS current spring version, 3.0.5)
- // TODO 3.1 GA: remove this block prior to 3.1 GA
- specContext.setEnvironment(parserContext.getDelegate().getEnvironment());
- } catch (NoSuchMethodError ex) {
- specContext.setEnvironment(new DefaultEnvironment());
- }
- try {
- // access the reader context's problem reporter reflectively in order to
- // compensate for tooling (STS) constraints around introduction of changes
- // to parser context / reader context classes.
- // TODO 3.1 GA: remove this block prior to 3.1 GA
- Field field = ReaderContext.class.getDeclaredField("problemReporter");
- field.setAccessible(true);
- ProblemReporter problemReporter = (ProblemReporter)field.get(parserContext.getReaderContext());
- specContext.setProblemReporter(problemReporter);
- } catch (Exception ex) {
- throw new IllegalStateException(
- "Could not access field 'ReaderContext#problemReporter' on object " +
- parserContext.getReaderContext(), ex);
- }
- return specContext;
- }
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationExecutor.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationExecutor.java
deleted file mode 100644
index 2f53047076e..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationExecutor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-import org.springframework.core.GenericTypeResolver;
-import org.springframework.util.Assert;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public abstract class AbstractSpecificationExecutor implements FeatureSpecificationExecutor {
-
- /**
- * {@inheritDoc}
- *
This implementation {@linkplain FeatureSpecification#validate() validates} the
- * given specification and delegates it to {@link #doExecute(FeatureSpecification)}
- * only if valid.
- */
- @SuppressWarnings("unchecked")
- public final void execute(FeatureSpecification spec, SpecificationContext specificationContext) {
- Assert.notNull(spec, "Specification must not be null");
- Assert.notNull(spec, "SpecificationContext must not be null");
- Class> typeArg = GenericTypeResolver.resolveTypeArgument(this.getClass(), AbstractSpecificationExecutor.class);
- Assert.isTrue(typeArg.equals(spec.getClass()), "Specification cannot be executed by this executor");
- if (spec.validate(specificationContext.getProblemReporter())) {
- doExecute((S)spec, specificationContext);
- }
- }
-
- /**
- * Execute the given specification, usually resulting in registration of bean definitions
- * against a bean factory.
- * @param specification the {@linkplain FeatureSpecification#validate() validated} specification
- */
- protected abstract void doExecute(S specification, SpecificationContext specificationContext);
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecification.java b/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecification.java
deleted file mode 100644
index 671414f9a58..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecification.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-import org.springframework.beans.factory.parsing.ProblemReporter;
-
-/**
- * Interface to be implemented by objects that specify the configuration of a particular feature
- * of the Spring container e.g., component-scanning, JMX MBean exporting, AspectJ auto-proxying,
- * annotation-driven transaction management, and so on.
- *
- *
Many features of the Spring container can be configured using either XML or annotations.
- * As one example, Spring's component scanning feature may be configured using
- * either the {@code } XML element or (as of Spring 3.1) the
- * {@code @ComponentScan} annotation. These two options are equivalent to one another, and users may
- * choose between them as a matter of convention or preference. Fundamentally, both are declarative
- * mechanisms for specifying how the Spring container should be configured. A {@code
- * FeatureSpecification} object, then, is a way of representing this configuration information independent
- * of its original source format be it XML, annotations, or otherwise.
- *
- * A {@code FeatureSpecification} is responsible for {@linkplain #validate validating itself}.
- * For example, a component-scanning specification would check that at least one base package has
- * been specified, and otherwise register a {@code Problem} with a {@link ProblemReporter}. Taking
- * this approach as opposed to throwing exceptions allows for maximum tooling and error reporting
- * flexibility.
- *
- *
A {@link FeatureSpecificationExecutor} is used to carry out the instructions within a populated
- * {@code FeatureSpecification}; this is where the "real work" happens. In the case of component scanning
- * as above, it is within a {@code FeatureSpecificationExecutor} that a bean definition scanner is created,
- * configured and invoked against the base packages specified.
- *
- *
{@code FeatureSpecification} objects may be populated and executed by Spring XML namespace element
- * parsers on order to separate the concerns of XML parsing from Spring bean definition creation and
- * registration. This type of use is mostly a framework-internal matter. More interesting to end users is
- * the use of {@code FeatureSpecification} objects within {@code @FeatureConfiguration} classes and their
- * {@code @Feature} methods. This functionality is new in Spring 3.1 and is the logical evolution of Spring's
- * Java-based configuration support first released in Spring 3.0 (see {@code @Configuration} classes and
- * {@code @Bean} methods). The primary goal of {@code Feature}-related support is to round out this
- * Java-based support and allow users to configure all aspects of the Spring-container without requiring
- * the use of XML. See "design notes" below for an example of this kind of use.
- *
- *
Notes on designing {@code FeatureSpecification} implementations
- *
- * The public API of a {@code FeatureSpecification} should be designed for maximum ease of use
- * within {@code @Feature} methods. Traditional JavaBean-style getters and setters should be dropped
- * for a more fluent style that allows for method chaining. Consider the following example of a
- * {@code @Feature} method:
- *
- *
- * @Feature
- * public TxAnnotationDriven tx(PlatformTransactionManager txManager) {
- * return new TxAnnotationDriven(txManager).proxyTargetClass(true);
- * }
- *
- *
- * Notice how the creation and configuration of the {@code TxAnnotationDriven} specification is
- * concise and reads well. This is facilitated by mutator methods that always return the
- * specification object's 'this' reference, allowing for method chaining. A secondary design goal
- * of this approach is that the resulting code tends to mirror corresponding XML namespace
- * declarations, which most Spring users are already familiar with. For example, compare the
- * code above with its XML counterpart:
- *
- * {@code }
- *
- *
Typically, a user will call only the constructor and 'mutator' methods of a specification
- * object. The accessor/getter methods, however, are typically called only by the specification's
- * {@linkplain FeatureSpecificationExecutor executor} for the purpose of populating and registering
- * bean definitions with the Spring container. For this reason, it is recommended that accessor
- * methods be given package-private visibility. This creates a better experience for users from
- * an IDE content-assist point of view as they will see only the public mutator methods, reducing
- * any possible confusion.
- *
- *
Implementations should take care to allow for use of string-based bean names, placeholder
- * ("${...}") and SpEL ("#{...}) expressions wherever they may be useful.
- * While it is generally desirable to refer to dependent beans in pure Java, in certain cases a
- * user may wish or need to refer to a bean by name. For example, the {@code TxAnnotationDriven} specification
- * referenced above allows for specifying its transaction-manager reference by {@code String} or by
- * {@code PlatformTransactionManager} reference. Such strings should always be candidates for placeholder
- * replacement and SpEL evaluation for maximum configurability as well as parity with the feature set
- * available in Spring XML. With regard to SpEL expressions, users should assume that only expressions
- * evaluating to a bean name will be supported. While it is technically possible with SpEL to resolve
- * a bean instance, specification executors will not support such use unless explicitly indicated.
- *
- *
See the Javadoc for {@code @FeatureConfiguration} classes and {@code @Feature} methods for
- * information on their lifecycle and semantics.
- *
- * @author Chris Beams
- * @since 3.1
- * @see FeatureSpecificationExecutor
- * @see AbstractSpecificationExecutor
- * @see org.springframework.context.annotation.Feature
- * @see org.springframework.context.annotation.FeatureConfiguration
- */
-public interface FeatureSpecification {
-
- /**
- * Validate this specification instance to ensure all required properties
- * have been set, including checks on mutually exclusive or mutually
- * dependent properties. May in some cases modify the state of the
- * specification e.g., instantiating types specified as strings.
- * @see AbstractSpecificationExecutor#execute(FeatureSpecification, SpecificationContext)
- * @return whether any problems occurred during validation
- */
- boolean validate(ProblemReporter problemReporter);
-
- /**
- * Execute this specification instance, carrying out the instructions
- * specified within. Should work by delegating to an underlying
- * {@link FeatureSpecificationExecutor} for proper separation of concerns.
- */
- void execute(SpecificationContext specificationContext);
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecificationExecutor.java b/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecificationExecutor.java
deleted file mode 100644
index 47237e33039..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/FeatureSpecificationExecutor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-/**
- * Interface for executing a populated {@link FeatureSpecification}. Provides
- * a generic mechanism for handling container configuration metadata regardless of
- * origin in XML, annotations, or other source format.
- *
- * TODO SPR-7420: document (clean up)
- *
- * @author Chris Beams
- * @since 3.1
- * @see AbstractSpecificationExecutor
- * @see org.springframework.beans.factory.xml.BeanDefinitionParser
- * @see org.springframework.context.annotation.FeatureAnnotationParser
- * @see org.springframework.context.annotation.ComponentScanExecutor
- */
-public interface FeatureSpecificationExecutor {
-
- /**
- * Execute the given specification, usually resulting in registration
- * of bean definitions against a bean factory.
- */
- void execute(FeatureSpecification spec, SpecificationContext specificationContext);
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/SourceAwareSpecification.java b/org.springframework.context/src/main/java/org/springframework/context/config/SourceAwareSpecification.java
deleted file mode 100644
index 82b6ea09cdd..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/SourceAwareSpecification.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public interface SourceAwareSpecification extends FeatureSpecification {
-
- String sourceName();
-
- SourceAwareSpecification sourceName(String sourceName);
-
- Object source();
-
- SourceAwareSpecification source(Object source);
-
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/SpecificationContext.java b/org.springframework.context/src/main/java/org/springframework/context/config/SpecificationContext.java
deleted file mode 100644
index 20c2d2ea363..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/context/config/SpecificationContext.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.config;
-
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.parsing.ProblemReporter;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.ResourceLoader;
-
-/**
- * TODO: rename to SpecificationContext?
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class SpecificationContext {
-
- private BeanDefinitionRegistry registry;
- private ComponentRegistrar registrar;
- private ResourceLoader resourceLoader;
- private Environment environment;
- private ProblemReporter problemReporter;
-
- public SpecificationContext() { }
-
- public void setRegistry(BeanDefinitionRegistry registry) {
- this.registry = registry;
- }
-
- public BeanDefinitionRegistry getRegistry() {
- return this.registry;
- }
-
- public void setRegistrar(ComponentRegistrar registrar) {
- this.registrar = registrar;
- }
-
- public ComponentRegistrar getRegistrar() {
- return this.registrar;
- }
-
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
-
- public ResourceLoader getResourceLoader() {
- return this.resourceLoader;
- }
-
- public void setEnvironment(Environment environment) {
- this.environment = environment;
- }
-
- public Environment getEnvironment() {
- return this.environment;
- }
-
- public void setProblemReporter(ProblemReporter problemReporter) {
- this.problemReporter = problemReporter;
- }
-
- public ProblemReporter getProblemReporter() {
- return this.problemReporter;
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanFactoryAwareFeatureConfigurationTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanFactoryAwareFeatureConfigurationTests.java
deleted file mode 100644
index 42f1c9b2a27..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanFactoryAwareFeatureConfigurationTests.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-/**
- * Tests that @FeatureConfiguration classes may implement Aware interfaces,
- * such as BeanFactoryAware. This is not generally recommended but occasionally
- * useful, particularly in testing.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class BeanFactoryAwareFeatureConfigurationTests {
- @Test
- public void test() {
- ConfigurableApplicationContext ctx =
- new AnnotationConfigApplicationContext(FeatureConfig.class);
- FeatureConfig fc = ctx.getBean(FeatureConfig.class);
- assertThat(fc.featureMethodWasCalled, is(true));
- assertThat(fc.gotBeanFactoryInTime, is(true));
- assertThat(fc.beanFactory, is(ctx.getBeanFactory()));
- }
-
- @FeatureConfiguration
- static class FeatureConfig implements BeanFactoryAware {
-
- ConfigurableListableBeanFactory beanFactory;
- boolean featureMethodWasCalled = false;
- boolean gotBeanFactoryInTime = false;
-
- public void setBeanFactory(BeanFactory beanFactory) {
- this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
- }
-
- @Feature
- public FeatureSpecification f() {
- this.featureMethodWasCalled = true;
- this.gotBeanFactoryInTime = (this.beanFactory != null);
- return new StubSpecification();
- }
- }
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanExecutorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanExecutorTests.java
deleted file mode 100644
index f419f1e8ee3..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanExecutorTests.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
-import org.springframework.beans.factory.parsing.FailFastProblemReporter;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.core.io.DefaultResourceLoader;
-import org.springframework.mock.env.MockEnvironment;
-
-/**
- * Unit tests for {@link ComponentScanExecutor}.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class ComponentScanExecutorTests {
-
- private ComponentScanExecutor executor;
- private SpecificationContext specificationContext;
- private DefaultListableBeanFactory bf;
-
- @Before
- public void setUp() {
- this.bf = new DefaultListableBeanFactory();
- this.executor = new ComponentScanExecutor();
- this.specificationContext = new SpecificationContext();
- this.specificationContext.setRegistry(bf);
- this.specificationContext.setResourceLoader(new DefaultResourceLoader());
- this.specificationContext.setEnvironment(new MockEnvironment());
- this.specificationContext.setRegistrar(new SimpleComponentRegistrar(bf));
- this.specificationContext.setProblemReporter(new FailFastProblemReporter());
- }
-
- @Test
- public void validSpec() {
- this.executor.execute(new ComponentScanSpec("example.scannable"), this.specificationContext);
- assertThat(bf.containsBean("fooServiceImpl"), is(true));
- }
-
- @Test(expected=BeanDefinitionParsingException.class)
- public void invalidSpec() {
- // ff problem reporter should throw due to no packages specified
- this.executor.execute(new ComponentScanSpec(), this.specificationContext);
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanFeatureTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanFeatureTests.java
deleted file mode 100644
index 8ddbd03240f..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanFeatureTests.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-
-public class ComponentScanFeatureTests {
- @Test
- public void viaContextRegistration() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(ComponentScanFeatureConfig.class);
- ctx.register(ComponentScanFeatureConfig.Features.class);
- ctx.refresh();
- ctx.getBean(ComponentScanFeatureConfig.class);
- ctx.getBean(TestBean.class);
- assertThat("config class bean not found", ctx.containsBeanDefinition("componentScanFeatureConfig"), is(true));
- assertThat("@ComponentScan annotated @Configuration class registered directly against " +
- "AnnotationConfigApplicationContext did not trigger component scanning as expected",
- ctx.containsBean("fooServiceImpl"), is(true));
- }
-}
-
-@Configuration
-//@Import(ComponentScanFeatureConfig.Features.class)
-class ComponentScanFeatureConfig {
- @FeatureConfiguration
- static class Features {
- @Feature
- public ComponentScanSpec componentScan() {
- return new ComponentScanSpec(example.scannable._package.class);
- }
- }
-
- @Bean
- public TestBean testBean() {
- return new TestBean();
- }
-}
\ No newline at end of file
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanSpecTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanSpecTests.java
deleted file mode 100644
index cc9f1ecbb81..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/ComponentScanSpecTests.java
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.springframework.util.StringUtils.arrayToCommaDelimitedString;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
-import org.springframework.beans.factory.parsing.FailFastProblemReporter;
-import org.springframework.beans.factory.parsing.Problem;
-import org.springframework.beans.factory.parsing.ProblemReporter;
-import org.springframework.beans.factory.support.BeanNameGenerator;
-import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.AnnotationTypeFilter;
-import org.springframework.core.type.filter.AssignableTypeFilter;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Unit tests for {@link ComponentScanSpec}.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class ComponentScanSpecTests {
-
- private CollatingProblemReporter problemReporter;
- private ClassLoader classLoader;
-
-
- @Before
- public void setUp() {
- problemReporter = new CollatingProblemReporter();
- classLoader = ClassUtils.getDefaultClassLoader();
- }
-
- @Test
- public void includeAnnotationConfig() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- assertThat(spec.includeAnnotationConfig(), nullValue());
- spec.includeAnnotationConfig(true);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(true));
- spec.includeAnnotationConfig(false);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(false));
- spec.includeAnnotationConfig("trUE");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(true));
- spec.includeAnnotationConfig("falSE");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(false));
- spec.includeAnnotationConfig("");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(false));
- spec.includeAnnotationConfig((String)null);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), is(false));
- spec.includeAnnotationConfig((Boolean)null);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeAnnotationConfig(), nullValue());
- }
-
- @Test
- public void resourcePattern() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- assertThat(spec.resourcePattern(), nullValue());
- assertThat(spec.validate(problemReporter), is(true));
- spec.resourcePattern("**/Foo*.class");
- assertThat(spec.resourcePattern(), is("**/Foo*.class"));
- assertThat(spec.validate(problemReporter), is(true));
- spec.resourcePattern("");
- assertThat(spec.resourcePattern(), is("**/Foo*.class"));
- assertThat(spec.validate(problemReporter), is(true));
- spec.resourcePattern(null);
- assertThat(spec.resourcePattern(), is("**/Foo*.class"));
- assertThat(spec.validate(problemReporter), is(true));
- }
-
- @Test
- public void useDefaultFilters() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- assertThat(spec.useDefaultFilters(), nullValue());
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters((Boolean)null);
- assertThat(spec.useDefaultFilters(), nullValue());
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters(true);
- assertThat(spec.useDefaultFilters(), is(true));
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters(false);
- assertThat(spec.useDefaultFilters(), is(false));
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters("trUE");
- assertThat(spec.useDefaultFilters(), is(true));
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters("falSE");
- assertThat(spec.useDefaultFilters(), is(false));
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters("");
- assertThat(spec.useDefaultFilters(), is(false));
- assertThat(spec.validate(problemReporter), is(true));
- spec.useDefaultFilters((String)null);
- assertThat(spec.useDefaultFilters(), is(false));
- assertThat(spec.validate(problemReporter), is(true));
- }
-
- @Test
- public void includeFilters() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.includeFilters(
- new AnnotationTypeFilter(MyAnnotation.class),
- new AssignableTypeFilter(Object.class));
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeFilters().length, is(2));
- }
-
- @Test
- public void stringIncludeExcludeFilters() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.addIncludeFilter("annotation", MyAnnotation.class.getName(), classLoader);
- spec.addExcludeFilter("assignable", Object.class.getName(), classLoader);
- spec.addExcludeFilter("annotation", Override.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.includeFilters().length, is(1));
- assertThat(spec.excludeFilters().length, is(2));
- }
-
- @Test
- public void bogusStringIncludeFilter() throws IOException {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.addIncludeFilter("bogus-type", "bogus-expr", classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- assertThat(spec.includeFilters().length, is(1));
- try {
- spec.includeFilters()[0].match(null, null);
- fail("expected placholder TypeFilter to throw exception");
- } catch (UnsupportedOperationException ex) {
- // expected
- }
- }
-
- @Test
- public void exerciseFilterTypes() throws IOException {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.addIncludeFilter("aspectj", "*..Bogus", classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- spec.addIncludeFilter("regex", ".*Foo", classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- spec.addIncludeFilter("custom", StubTypeFilter.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- spec.addIncludeFilter("custom", "org.NonExistentTypeFilter", classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- spec.addIncludeFilter("custom", NonNoArgResolver.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void missingBasePackages() {
- ComponentScanSpec spec = new ComponentScanSpec();
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void withBasePackageViaAdderMethod() {
- ComponentScanSpec spec = new ComponentScanSpec();
- spec.addBasePackage("org.p1");
- spec.addBasePackage("org.p2");
- assertThat(spec.validate(problemReporter), is(true));
- assertExactContents(spec.basePackages(), "org.p1", "org.p2");
- }
-
- @Test
- public void withBasePackagesViaStringConstructor() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1", "org.p2");
- assertThat(spec.validate(problemReporter), is(true));
- assertExactContents(spec.basePackages(), "org.p1", "org.p2");
- }
-
- @Test
- public void withBasePackagesViaClassConstructor() {
- ComponentScanSpec spec = new ComponentScanSpec(java.lang.Object.class, java.io.Closeable.class);
- assertThat(spec.validate(problemReporter), is(true));
- assertExactContents(spec.basePackages(), "java.lang", "java.io");
- }
-
- @Test
- public void forDelimitedPackages() {
- ComponentScanSpec spec = ComponentScanSpec.forDelimitedPackages("pkg.one,pkg.two");
- assertTrue(ObjectUtils.containsElement(spec.basePackages(), "pkg.one"));
- assertTrue(ObjectUtils.containsElement(spec.basePackages(), "pkg.two"));
- assertThat(spec.basePackages().length, is(2));
- }
-
- @Test
- public void withSomeEmptyBasePackages() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1", "", "org.p3");
- assertThat(spec.validate(problemReporter), is(true));
- assertExactContents(spec.basePackages(), "org.p1", "org.p3");
- }
-
- @Test
- public void withAllEmptyBasePackages() {
- ComponentScanSpec spec = new ComponentScanSpec("", "", "");
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void withInstanceBeanNameGenerator() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- assertThat(spec.beanNameGenerator(), nullValue());
- BeanNameGenerator bng = new DefaultBeanNameGenerator();
- spec.beanNameGenerator(bng);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.beanNameGenerator(), is(bng));
- }
-
- @Test
- public void withStringBeanNameGenerator() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.beanNameGenerator(DefaultBeanNameGenerator.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.beanNameGenerator(), instanceOf(DefaultBeanNameGenerator.class));
- }
-
- @Test
- public void withInstanceScopeMetadataResolver() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- assertThat(spec.scopeMetadataResolver(), nullValue());
- ScopeMetadataResolver smr = new AnnotationScopeMetadataResolver();
- spec.scopeMetadataResolver(smr);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.scopeMetadataResolver(), is(smr));
- }
-
- @Test
- public void withStringScopeMetadataResolver() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopeMetadataResolver(AnnotationScopeMetadataResolver.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.scopeMetadataResolver(), instanceOf(AnnotationScopeMetadataResolver.class));
- }
-
- @Test
- public void withNonAssignableStringScopeMetadataResolver() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopeMetadataResolver(Object.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void withNonExistentStringScopeMetadataResolver() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopeMetadataResolver("org.Bogus", classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void withNonNoArgStringScopeMetadataResolver() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopeMetadataResolver(NonNoArgResolver.class.getName(), classLoader);
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void withStringScopedProxyMode() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopedProxyMode("targetCLASS");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.scopedProxyMode(), is(ScopedProxyMode.TARGET_CLASS));
- spec.scopedProxyMode("interFACES");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.scopedProxyMode(), is(ScopedProxyMode.INTERFACES));
- spec.scopedProxyMode("nO");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.scopedProxyMode(), is(ScopedProxyMode.NO));
- spec.scopedProxyMode("bogus");
- assertThat(spec.validate(problemReporter), is(false));
- assertThat(spec.scopedProxyMode(), nullValue());
- }
-
- @Test
- public void withScopeMetadataResolverAndScopedProxyMode() {
- ComponentScanSpec spec = new ComponentScanSpec("org.p1");
- spec.scopeMetadataResolver(new AnnotationScopeMetadataResolver());
- assertThat(spec.validate(problemReporter), is(true));
- spec.scopedProxyMode(ScopedProxyMode.INTERFACES);
- assertThat(spec.validate(problemReporter), is(false));
- }
-
- @Test
- public void addBasePackage() {
- ComponentScanSpec spec = new ComponentScanSpec();
- spec.addBasePackage("foo.bar");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.basePackages().length, is(1));
- }
-
- @Test
- public void addBasePackageWithConstructor() {
- ComponentScanSpec spec = new ComponentScanSpec("my.pkg");
- spec.addBasePackage("foo.bar");
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.basePackages().length, is(2));
- }
-
- @Test
- public void addExcludeFilterString() {
- ComponentScanSpec spec = new ComponentScanSpec("my.pkg");
- spec.addExcludeFilter("annotation", MyAnnotation.class.getName(), ClassUtils.getDefaultClassLoader());
- assertThat(spec.validate(problemReporter), is(true));
- assertThat(spec.excludeFilters().length, is(1));
- assertThat(spec.excludeFilters()[0], instanceOf(AnnotationTypeFilter.class));
- }
-
- @Test(expected=BeanDefinitionParsingException.class)
- public void withFailFastProblemReporter() {
- new ComponentScanSpec().validate(new FailFastProblemReporter());
- }
-
- private void assertExactContents(T[] actual, T... expected) {
- if (actual.length >= expected.length) {
- for (int i = 0; i < expected.length; i++) {
- assertThat(
- String.format("element number %d in actual is incorrect. actual: [%s], expected: [%s]",
- i, arrayToCommaDelimitedString(actual), arrayToCommaDelimitedString(expected)),
- actual[i], equalTo(expected[i]));
- }
- }
- assertThat(String.format("actual contains incorrect number of arguments. actual: [%s], expected: [%s]",
- arrayToCommaDelimitedString(actual), arrayToCommaDelimitedString(expected)),
- actual.length, equalTo(expected.length));
- }
-
-
- private static class CollatingProblemReporter implements ProblemReporter {
-
- private List errors = new ArrayList();
-
- private List warnings = new ArrayList();
-
-
- public void fatal(Problem problem) {
- throw new BeanDefinitionParsingException(problem);
- }
-
- public void error(Problem problem) {
- this.errors.add(problem);
- }
-
- @SuppressWarnings("unused")
- public Problem[] getErrors() {
- return this.errors.toArray(new Problem[this.errors.size()]);
- }
-
- public void warning(Problem problem) {
- System.out.println(problem);
- this.warnings.add(problem);
- }
-
- @SuppressWarnings("unused")
- public Problem[] getWarnings() {
- return this.warnings.toArray(new Problem[this.warnings.size()]);
- }
- }
-
-
- private static class NonNoArgResolver implements ScopeMetadataResolver {
- public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
- throw new UnsupportedOperationException();
- }
- }
-
- private static class StubTypeFilter implements TypeFilter {
- public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
- throws IOException {
- throw new UnsupportedOperationException();
- }
- }
-
-}
\ No newline at end of file
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreatorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreatorTests.java
deleted file mode 100644
index d5813821e7f..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/EarlyBeanReferenceProxyCreatorTests.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static java.lang.String.format;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.sameInstance;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.springframework.context.annotation.EarlyBeanReferenceProxyCreator.MISSING_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE;
-import static org.springframework.context.annotation.EarlyBeanReferenceProxyCreator.PRIVATE_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE;
-
-import java.lang.reflect.Method;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.config.DependencyDescriptor;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.core.MethodParameter;
-
-import test.beans.ITestBean;
-import test.beans.TestBean;
-
-/**
- * Unit tests for {@link EarlyBeanReferenceProxyCreator}, ensuring that
- * {@link EarlyBeanReferenceProxy} objects behave properly.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class EarlyBeanReferenceProxyCreatorTests {
-
- private DefaultListableBeanFactory bf;
-
- @Before
- public void setUp() {
- bf = new DefaultListableBeanFactory();
- }
-
- @Test
- public void proxyToStringAvoidsEagerInstantiation() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
-
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(proxy.toString(), equalTo("EarlyBeanReferenceProxy for bean of type TestBean"));
- }
-
- @Test(expected=NoSuchBeanDefinitionException.class)
- public void proxyThrowsNoSuchBeanDefinitionExceptionWhenDelegatingMethodCallToNonExistentBean() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- proxy.getName();
- }
-
- @Test
- public void proxyHashCodeAvoidsEagerInstantiation() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(proxy.hashCode(), equalTo(System.identityHashCode(proxy)));
- }
-
- @Test
- public void proxyEqualsAvoidsEagerInstantiation() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
-
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(proxy.equals(new Object()), is(false));
- assertThat(proxy.equals(proxy), is(true));
-
- TestBean proxy2 = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(proxy, not(sameInstance(proxy2)));
- assertThat(proxy.equals(proxy2), is(false));
- assertThat(proxy2.equals(proxy), is(false));
- assertThat(proxy2.equals(proxy2), is(true));
- }
-
- @Test
- public void proxyFinalizeAvoidsEagerInstantiation() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
-
- BeanWithFinalizer proxy = (BeanWithFinalizer) pc.createProxyIfPossible(descriptorFor(BeanWithFinalizer.class));
-
- assertThat(BeanWithFinalizer.finalizerWasCalled, is(false));
- BeanWithFinalizer.class.getDeclaredMethod("finalize").invoke(proxy);
- assertThat(BeanWithFinalizer.finalizerWasCalled, is(false));
- }
-
- @Test
- public void proxyMethodsDelegateToTargetBeanCausingSingletonRegistrationIfNecessary() throws Exception {
- bf.registerBeanDefinition("testBean",
- BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
- .addPropertyValue("name", "testBeanName").getBeanDefinition());
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(bf.containsBeanDefinition("testBean"), is(true));
- assertThat(bf.containsSingleton("testBean"), is(false));
- assertThat(proxy.getName(), equalTo("testBeanName"));
- assertThat(bf.containsSingleton("testBean"), is(true));
- }
-
- @Test
- public void beanAnnotatedMethodsReturnEarlyProxyAsWell() throws Exception {
- bf.registerBeanDefinition("componentWithInterfaceBeanMethod", new RootBeanDefinition(ComponentWithInterfaceBeanMethod.class));
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- ComponentWithInterfaceBeanMethod proxy = (ComponentWithInterfaceBeanMethod) pc.createProxyIfPossible(descriptorFor(ComponentWithInterfaceBeanMethod.class));
-
- ITestBean bean = proxy.aBeanMethod();
- assertThat(bean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(bf.containsBeanDefinition("componentWithInterfaceBeanMethod"), is(true));
- assertThat("calling a @Bean method on an EarlyBeanReferenceProxy object " +
- "should not cause its instantation/registration",
- bf.containsSingleton("componentWithInterfaceBeanMethod"), is(false));
-
- Object obj = proxy.normalInstanceMethod();
- assertThat(bf.containsSingleton("componentWithInterfaceBeanMethod"), is(true));
- assertThat(obj, not(instanceOf(EarlyBeanReferenceProxy.class)));
- }
-
- @Test
- public void proxiesReturnedFromBeanAnnotatedMethodsDereferenceAndDelegateToTheirTargetBean() throws Exception {
- bf.registerBeanDefinition("componentWithConcreteBeanMethod", new RootBeanDefinition(ComponentWithConcreteBeanMethod.class));
- RootBeanDefinition beanMethodBeanDef = new RootBeanDefinition();
- beanMethodBeanDef.setFactoryBeanName("componentWithConcreteBeanMethod");
- beanMethodBeanDef.setFactoryMethodName("aBeanMethod");
- bf.registerBeanDefinition("aBeanMethod", beanMethodBeanDef);
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- ComponentWithConcreteBeanMethod proxy = (ComponentWithConcreteBeanMethod) pc.createProxyIfPossible(descriptorFor(ComponentWithConcreteBeanMethod.class));
-
- TestBean bean = proxy.aBeanMethod();
- assertThat(bean.getName(), equalTo("concrete"));
- }
-
- @Test
- public void interfaceBeansAreProxied() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- ITestBean proxy = (ITestBean) pc.createProxyIfPossible(descriptorFor(ITestBean.class));
-
- assertThat(proxy, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(AopUtils.isCglibProxyClass(proxy.getClass()), is(true));
- assertEquals(
- "interface-based bean proxies should have Object as superclass",
- proxy.getClass().getSuperclass(), Object.class);
- }
-
- @Test
- public void concreteBeansAreProxied() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- TestBean proxy = (TestBean) pc.createProxyIfPossible(descriptorFor(TestBean.class));
-
- assertThat(proxy, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(AopUtils.isCglibProxyClass(proxy.getClass()), is(true));
- assertEquals(
- "concrete bean proxies should have the bean class as superclass",
- proxy.getClass().getSuperclass(), TestBean.class);
- }
-
- @Test
- public void beanAnnotatedMethodsWithInterfaceReturnTypeAreProxied() throws Exception {
- bf.registerBeanDefinition("componentWithInterfaceBeanMethod", new RootBeanDefinition(ComponentWithInterfaceBeanMethod.class));
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- ComponentWithInterfaceBeanMethod proxy = (ComponentWithInterfaceBeanMethod) pc.createProxyIfPossible(descriptorFor(ComponentWithInterfaceBeanMethod.class));
-
- ITestBean bean = proxy.aBeanMethod();
- assertThat(bean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(AopUtils.isCglibProxyClass(bean.getClass()), is(true));
- assertEquals(
- "interface-based bean proxies should have Object as superclass",
- bean.getClass().getSuperclass(), Object.class);
- }
-
- @Test
- public void beanAnnotatedMethodsWithConcreteReturnTypeAreProxied() throws Exception {
- bf.registerBeanDefinition("componentWithConcreteBeanMethod", new RootBeanDefinition(ComponentWithConcreteBeanMethod.class));
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- ComponentWithConcreteBeanMethod proxy = (ComponentWithConcreteBeanMethod) pc.createProxyIfPossible(descriptorFor(ComponentWithConcreteBeanMethod.class));
-
- TestBean bean = proxy.aBeanMethod();
- assertThat(bean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(AopUtils.isCglibProxyClass(bean.getClass()), is(true));
- assertEquals(
- "concrete bean proxies should have the bean class as superclass",
- bean.getClass().getSuperclass(), TestBean.class);
- }
-
- @Test
- public void attemptToProxyClassMissingNoArgConstructorFailsGracefully() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- try {
- pc.createProxyIfPossible(descriptorFor(BeanMissingNoArgConstructor.class));
- fail("expected ProxyCreationException");
- } catch(ProxyCreationException ex) {
- assertThat(ex.getMessage(),
- equalTo(format(MISSING_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE, BeanMissingNoArgConstructor.class.getName())));
- }
- }
-
- @Test
- public void attemptToProxyClassWithPrivateNoArgConstructorFailsGracefully() throws Exception {
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- try {
- pc.createProxyIfPossible(descriptorFor(BeanWithPrivateNoArgConstructor.class));
- fail("expected ProxyCreationException");
- } catch(ProxyCreationException ex) {
- assertThat(ex.getMessage(),
- equalTo(format(PRIVATE_NO_ARG_CONSTRUCTOR_ERROR_MESSAGE, BeanWithPrivateNoArgConstructor.class.getName())));
- }
- }
-
- @Test
- public void attemptToProxyFinalClassReturnsNonProxiedInstance() throws Exception {
- bf.registerBeanDefinition("finalBean", new RootBeanDefinition(FinalBean.class));
- EarlyBeanReferenceProxyCreator pc = new EarlyBeanReferenceProxyCreator(bf);
- Object bean = pc.createProxyIfPossible(descriptorFor(FinalBean.class));
- assertThat(bean, instanceOf(FinalBean.class));
- assertThat(bean, not(instanceOf(EarlyBeanReferenceProxy.class)));
- }
-
- private DependencyDescriptor descriptorFor(Class> paramType) throws Exception {
- @SuppressWarnings("unused")
- class C {
- void m(ITestBean p) { }
- void m(TestBean p) { }
- void m(BeanMissingNoArgConstructor p) { }
- void m(BeanWithPrivateNoArgConstructor p) { }
- void m(FinalBean p) { }
- void m(BeanWithFinalizer p) { }
- void m(ComponentWithConcreteBeanMethod p) { }
- void m(ComponentWithInterfaceBeanMethod p) { }
- }
-
- Method targetMethod = C.class.getDeclaredMethod("m", new Class>[] { paramType });
- MethodParameter mp = new MethodParameter(targetMethod, 0);
- DependencyDescriptor dd = new DependencyDescriptor(mp, true, false);
- return dd;
- }
-
-
- static class BeanMissingNoArgConstructor {
- BeanMissingNoArgConstructor(Object o) { }
- }
-
-
- static class BeanWithPrivateNoArgConstructor {
- private BeanWithPrivateNoArgConstructor() { }
- }
-
-
- static final class FinalBean {
- }
-
-
- static class BeanWithFinalizer {
- static Boolean finalizerWasCalled = false;
-
- @Override
- protected void finalize() throws Throwable {
- finalizerWasCalled = true;
- }
- }
-
-
- static class ComponentWithConcreteBeanMethod {
- @Bean
- public TestBean aBeanMethod() {
- return new TestBean("concrete");
- }
-
- public Object normalInstanceMethod() {
- return new Object();
- }
- }
-
-
- static class ComponentWithInterfaceBeanMethod {
- @Bean
- public ITestBean aBeanMethod() {
- return new TestBean("interface");
- }
-
- public Object normalInstanceMethod() {
- return new Object();
- }
- }
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationClassTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationClassTests.java
deleted file mode 100644
index e2610ac3b06..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationClassTests.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.mock.env.MockEnvironment;
-
-public class FeatureConfigurationClassTests {
-
- @Test(expected=FeatureMethodExecutionException.class)
- public void featureConfigurationClassesMustNotContainBeanAnnotatedMethods() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(FeatureConfigWithBeanAnnotatedMethod.class);
- ctx.refresh();
- }
-
- @Test
- public void featureMethodsMayAcceptResourceLoaderParameter() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.setDisplayName("enclosing app ctx");
- ctx.setEnvironment(new MockEnvironment().withProperty("foo", "bar"));
- ctx.register(FeatureMethodWithResourceLoaderParameter.class);
- ctx.refresh();
- }
-
-}
-
-
-@FeatureConfiguration
-class FeatureConfigWithBeanAnnotatedMethod {
- /**
- * This is illegal use. @FeatureConfiguration classes cannot have @Bean methods.
- */
- @Bean
- public TestBean testBean() {
- return new TestBean();
- }
-
- /**
- * This will never get called. An exception will first be raised regarding the illegal @Bean method above.
- */
- @Feature
- public FeatureSpecification feature() {
- return new StubSpecification();
- }
-}
-
-@FeatureConfiguration
-class FeatureMethodWithResourceLoaderParameter {
- @Feature
- public FeatureSpecification feature(ResourceLoader rl,
- Environment e) {
- // prove that the injected Environment is that of the enclosing app context
- assertThat(e.getProperty("foo"), is("bar"));
- // prove that the injected ResourceLoader is actually the enclosing application context
- Object target = ((EarlyBeanReferenceProxy)rl).dereferenceTargetBean();
- assertThat(target, instanceOf(AnnotationConfigApplicationContext.class));
- assertThat(((AnnotationConfigApplicationContext)target).getDisplayName(), is("enclosing app ctx"));
- return new StubSpecification();
- }
-}
\ No newline at end of file
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests-context.xml b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests-context.xml
deleted file mode 100644
index 930cadfa379..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests-context.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests.java
deleted file mode 100644
index 466e65b14e3..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportResourceTests.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-import test.beans.TestBean;
-
-/**
- * Tests proving that @FeatureConfiguration classes may be use @ImportResource
- * and then parameter autowire beans declared in the imported resource(s).
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureConfigurationImportResourceTests {
-
- @Test
- public void importResourceFromFeatureConfiguration() {
- ApplicationContext ctx =
- new AnnotationConfigApplicationContext(ImportingFeatureConfig.class);
- TestBean testBean = ctx.getBean(TestBean.class);
- assertThat(testBean.getName(), equalTo("beanFromXml"));
-
- // and just quickly prove that the target of the bean proxied for the Feature method
- // is indeed the same singleton instance as the one we just pulled from the container
- ImportingFeatureConfig ifc = ctx.getBean(ImportingFeatureConfig.class);
- TestBean proxyBean = ifc.testBean;
- assertThat(proxyBean, instanceOf(EarlyBeanReferenceProxy.class));
- assertNotSame(proxyBean, testBean);
- assertSame(((EarlyBeanReferenceProxy)proxyBean).dereferenceTargetBean(), testBean);
- }
-
- @FeatureConfiguration
- @ImportResource("org/springframework/context/annotation/FeatureConfigurationImportResourceTests-context.xml")
- static class ImportingFeatureConfig {
- TestBean testBean;
-
- @Feature
- public FeatureSpecification f(TestBean testBean) {
- this.testBean = testBean;
- return new StubSpecification();
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportTests.java
deleted file mode 100644
index 53141541225..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureConfigurationImportTests.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-/**
- * Tests proving that @Configuration classes may @Import @FeatureConfiguration
- * classes, and vice versa.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureConfigurationImportTests {
-
- @Test
- public void importFeatureConfigurationFromConfiguration() {
- ConfigurableApplicationContext ctx =
- new AnnotationConfigApplicationContext(ImportingConfig.class);
- ImportedFeatureConfig ifc = ctx.getBean(ImportedFeatureConfig.class);
- assertThat(
- "@FeatureConfiguration class was imported and registered " +
- "as a bean but its @Feature method was never called",
- ifc.featureMethodWasCalled, is(true));
- }
-
- @Test
- public void importConfigurationFromFeatureConfiguration() {
- ConfigurableApplicationContext ctx =
- new AnnotationConfigApplicationContext(ImportingFeatureConfig.class);
- ImportingFeatureConfig ifc = ctx.getBean(ImportingFeatureConfig.class);
- ImportedConfig ic = ctx.getBean(ImportedConfig.class);
- assertThat(
- "@FeatureConfiguration class was registered directly against " +
- "the container but its @Feature method was never called",
- ifc.featureMethodWasCalled, is(true));
- assertThat(
- "@Configuration class was @Imported but its @Bean method" +
- "was never registered / called",
- ic.beanMethodWasCalled, is(true));
- }
-
-
- @Configuration
- @Import(ImportedFeatureConfig.class)
- static class ImportingConfig {
- }
-
-
- @FeatureConfiguration
- static class ImportedFeatureConfig {
- boolean featureMethodWasCalled = false;
-
- @Feature
- public FeatureSpecification f() {
- this.featureMethodWasCalled = true;
- return new StubSpecification();
- }
- }
-
-
- @Configuration
- static class ImportedConfig {
- boolean beanMethodWasCalled = true;
- @Bean
- public TestBean testBean() {
- this.beanMethodWasCalled = true;
- return new TestBean();
- }
- }
-
-
- @FeatureConfiguration
- @Import(ImportedConfig.class)
- static class ImportingFeatureConfig {
- boolean featureMethodWasCalled = false;
-
- @Feature
- public FeatureSpecification f() {
- this.featureMethodWasCalled = true;
- return new StubSpecification();
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodBeanReferenceTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodBeanReferenceTests.java
deleted file mode 100644
index bab82187afb..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodBeanReferenceTests.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-import test.beans.ITestBean;
-import test.beans.TestBean;
-
-/**
- * Tests proving that @Feature methods may reference the product of @Bean methods.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureMethodBeanReferenceTests {
-
- @Test
- public void test() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(FeatureConfig.class, Config.class);
- ctx.refresh();
-
- TestBean registeredBean = ctx.getBean("testBean", TestBean.class);
- TestBean proxiedBean = ctx.getBean(FeatureConfig.class).testBean;
-
- assertThat(registeredBean, not(instanceOf(EarlyBeanReferenceProxy.class)));
- assertThat(proxiedBean, notNullValue());
- assertThat(proxiedBean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(proxiedBean.getSpouse(), is(registeredBean.getSpouse()));
- }
-
-
- @FeatureConfiguration
- static class FeatureConfig {
- TestBean testBean;
-
- @Feature
- public FeatureSpecification f(TestBean testBean) {
- this.testBean = testBean;
- return new StubSpecification();
- }
- }
-
-
- @Configuration
- static class Config {
- @Bean
- public ITestBean testBean() {
- return new TestBean(new TestBean("mySpouse"));
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodEarlyBeanProxyTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodEarlyBeanProxyTests.java
deleted file mode 100644
index 62784a84a34..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodEarlyBeanProxyTests.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-import test.beans.ITestBean;
-import test.beans.TestBean;
-
-/**
- * Tests that @Bean methods referenced from within @Feature methods
- * get proxied early to avoid premature instantiation of actual
- * bean instances.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureMethodEarlyBeanProxyTests {
-
- @Test
- public void earlyProxyCreationAndBeanRegistrationLifecycle() {
- AnnotationConfigApplicationContext ctx =
- new AnnotationConfigApplicationContext(FeatureConfig.class);
-
- //
- // see additional assertions in FeatureConfig#feature()
- //
-
- // sanity check that all the bean definitions we expecting are present
- assertThat(ctx.getBeanFactory().containsBeanDefinition("lazyHelperBean"), is(true));
- assertThat(ctx.getBeanFactory().containsBeanDefinition("eagerHelperBean"), is(true));
- assertThat(ctx.getBeanFactory().containsBeanDefinition("lazyPassthroughBean"), is(true));
- assertThat(ctx.getBeanFactory().containsBeanDefinition("eagerPassthroughBean"), is(true));
-
-
- // the lazy helper bean had methods invoked during feature method execution. it should be registered
- assertThat(ctx.getBeanFactory().containsSingleton("lazyHelperBean"), is(true));
-
- // the eager helper bean had methods invoked but should be registered in any case is it is non-lazy
- assertThat(ctx.getBeanFactory().containsSingleton("eagerHelperBean"), is(true));
-
- // the lazy passthrough bean was referenced in the feature method, but never invoked. it should not be registered
- assertThat(ctx.getBeanFactory().containsSingleton("lazyPassthroughBean"), is(false));
-
- // the eager passthrough bean should be registered in any case as it is non-lazy
- assertThat(ctx.getBeanFactory().containsSingleton("eagerPassthroughBean"), is(true));
-
-
- // now actually fetch all the beans. none should be proxies
- assertThat(ctx.getBean("lazyHelperBean"), not(instanceOf(EarlyBeanReferenceProxy.class)));
- assertThat(ctx.getBean("eagerHelperBean"), not(instanceOf(EarlyBeanReferenceProxy.class)));
- assertThat(ctx.getBean("lazyPassthroughBean"), not(instanceOf(EarlyBeanReferenceProxy.class)));
- assertThat(ctx.getBean("eagerPassthroughBean"), not(instanceOf(EarlyBeanReferenceProxy.class)));
- }
-
-
- @Test
- public void earlyProxyBeansMayBeInterfaceBasedOrConcrete() {
- new AnnotationConfigApplicationContext(FeatureConfigReferencingNonInterfaceBeans.class);
- }
-}
-
-
-@FeatureConfiguration
-@Import(TestBeanConfig.class)
-class FeatureConfig implements BeanFactoryAware {
- private DefaultListableBeanFactory beanFactory;
-
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- this.beanFactory = (DefaultListableBeanFactory)beanFactory;
- }
-
- @Feature
- public StubSpecification feature(TestBeanConfig beans) {
-
- assertThat(
- "The @Configuration class instance itself should be an early-ref proxy",
- beans, instanceOf(EarlyBeanReferenceProxy.class));
-
- // invocation of @Bean methods within @Feature methods should return proxies
- ITestBean lazyHelperBean = beans.lazyHelperBean();
- ITestBean eagerHelperBean = beans.eagerHelperBean();
- ITestBean lazyPassthroughBean = beans.lazyPassthroughBean();
- ITestBean eagerPassthroughBean = beans.eagerPassthroughBean();
-
- assertThat(lazyHelperBean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(eagerHelperBean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(lazyPassthroughBean, instanceOf(EarlyBeanReferenceProxy.class));
- assertThat(eagerPassthroughBean, instanceOf(EarlyBeanReferenceProxy.class));
-
- // but at this point, the proxy instances should not have
- // been registered as singletons with the container.
- assertThat(this.beanFactory.containsSingleton("lazyHelperBean"), is(false));
- assertThat(this.beanFactory.containsSingleton("eagerHelperBean"), is(false));
- assertThat(this.beanFactory.containsSingleton("lazyPassthroughBean"), is(false));
- assertThat(this.beanFactory.containsSingleton("eagerPassthroughBean"), is(false));
-
- // invoking a method on the proxy should cause it to pass through
- // to the container, instantiate the actual bean in question and
- // register that actual underlying instance as a singleton.
- assertThat(lazyHelperBean.getName(), equalTo("lazyHelper"));
- assertThat(eagerHelperBean.getName(), equalTo("eagerHelper"));
-
- assertThat(this.beanFactory.containsSingleton("lazyHelperBean"), is(true));
- assertThat(this.beanFactory.containsSingleton("eagerHelperBean"), is(true));
-
- // since no methods were called on the passthrough beans, they should remain
- // uncreated / unregistered.
- assertThat(this.beanFactory.containsSingleton("lazyPassthroughBean"), is(false));
- assertThat(this.beanFactory.containsSingleton("eagerPassthroughBean"), is(false));
-
- return new StubSpecification();
- }
-}
-
-
-@Configuration
-class TestBeanConfig {
-
- @Lazy @Bean
- public ITestBean lazyHelperBean() {
- return new TestBean("lazyHelper");
- }
-
- @Bean
- public ITestBean eagerHelperBean() {
- return new TestBean("eagerHelper");
- }
-
- @Lazy @Bean
- public ITestBean lazyPassthroughBean() {
- return new TestBean("lazyPassthrough");
- }
-
- @Bean
- public ITestBean eagerPassthroughBean() {
- return new TestBean("eagerPassthrough");
- }
-
-}
-
-
-@FeatureConfiguration
-@Import(NonInterfaceBeans.class)
-class FeatureConfigReferencingNonInterfaceBeans {
- @Feature
- public FeatureSpecification feature1(NonInterfaceBeans beans) throws Throwable {
- beans.testBean();
- return new StubSpecification();
- }
-
- @Feature
- public FeatureSpecification feature2(TestBean testBean) throws Throwable {
- return new StubSpecification();
- }
-}
-
-
-@Configuration
-class NonInterfaceBeans {
- @Bean
- public TestBean testBean() {
- return new TestBean("invalid");
- }
-}
-
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodErrorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodErrorTests.java
deleted file mode 100644
index 10566d58918..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodErrorTests.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-import test.beans.TestBean;
-
-/**
- * Tests proving that @Feature methods may reference the product of @Bean methods.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureMethodErrorTests {
-
- @Test
- public void incorrectReturnType() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(FeatureConfig.class);
- try {
- ctx.refresh();
- fail("expected exception");
- } catch (FeatureMethodExecutionException ex) {
- assertThat(ex.getCause().getMessage(),
- equalTo("Return type for @Feature method FeatureConfig.f() must be " +
- "assignable to FeatureSpecification"));
- }
- }
-
- @Test
- public void voidReturnType() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(VoidFeatureConfig.class);
- try {
- ctx.refresh();
- fail("expected exception");
- } catch (FeatureMethodExecutionException ex) {
- assertThat(ex.getCause().getMessage(),
- equalTo("Return type for @Feature method VoidFeatureConfig.f() must be " +
- "assignable to FeatureSpecification"));
- }
- }
-
- @Test
- public void containsBeanMethod() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(FeatureConfigWithBeanMethod.class);
- try {
- ctx.refresh();
- fail("expected exception");
- } catch (FeatureMethodExecutionException ex) {
- assertThat(ex.getMessage(),
- equalTo("@FeatureConfiguration classes must not contain @Bean-annotated methods. " +
- "FeatureConfigWithBeanMethod.testBean() is annotated with @Bean and must " +
- "be removed in order to proceed. Consider moving this method into a dedicated " +
- "@Configuration class and injecting the bean as a parameter into any @Feature " +
- "method(s) that need it."));
- }
- }
-
-
- @FeatureConfiguration
- static class FeatureConfig {
- @Feature
- public Object f() {
- return new StubSpecification();
- }
- }
-
-
- @FeatureConfiguration
- static class VoidFeatureConfig {
- @Feature
- public void f() {
- }
- }
-
-
- @FeatureConfiguration
- static class FeatureConfigWithBeanMethod {
- @Feature
- public FeatureSpecification f() {
- return new StubSpecification();
- }
-
- @Bean
- public TestBean testBean() {
- return new TestBean();
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodQualifiedBeanReferenceTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodQualifiedBeanReferenceTests.java
deleted file mode 100644
index 5ea134eb330..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodQualifiedBeanReferenceTests.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.FeatureSpecification;
-
-import test.beans.ITestBean;
-import test.beans.TestBean;
-
-/**
- * Tests proving that @Feature methods may reference beans using @Qualifier
- * as a parameter annotation.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class FeatureMethodQualifiedBeanReferenceTests {
-
- @Test
- public void test() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(Features.class, TestBeans.class);
- ctx.refresh();
- }
-
- @FeatureConfiguration
- static class Features {
-
- @Feature
- public FeatureSpecification f(@Qualifier("testBean1") ITestBean testBean) {
- assertThat(testBean.getName(), equalTo("one"));
- return new StubSpecification();
- }
-
- }
-
- @Configuration
- static class TestBeans {
- @Bean
- public ITestBean testBean1() {
- return new TestBean("one");
- }
-
- @Bean
- public ITestBean testBean2() {
- return new TestBean("two");
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodValueInjectionTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodValueInjectionTests.java
deleted file mode 100644
index 71d0c0dd0b3..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FeatureMethodValueInjectionTests.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.configuration.StubSpecification;
-
-/**
- * Tests ensuring that @Feature methods can accept @Value-annoted
- * parameters, particularly String types. SPR-7974 revealed this
- * was failing due to attempting to proxy objects of type String,
- * which cannot be done.
- *
- * @author Chris Beams
- */
-public class FeatureMethodValueInjectionTests {
-
- @Test
- public void control() {
- System.setProperty("foo", "bar");
- System.setProperty("num", "2");
- Config config = new AnnotationConfigApplicationContext(Config.class).getBean(Config.class);
- System.clearProperty("foo");
- System.clearProperty("num");
- assertThat(config.foo, is("bar"));
- assertThat(config.num, is(2));
- }
-
- @Test
- public void spelValueInjection() {
- System.setProperty("foo", "bar");
- new AnnotationConfigApplicationContext(SpelValueInjectionFeatureConfig.class);
- System.clearProperty("foo");
- }
-
- @Test
- public void spelIntValueInjection() {
- System.setProperty("num", "5");
- new AnnotationConfigApplicationContext(SpelIntValueInjectionFeatureConfig.class);
- System.clearProperty("num");
- }
-
- @Test
- public void stringBeanInjection() {
- new AnnotationConfigApplicationContext(StringBeanConfig.class, StringBeanInjectionByTypeFeatureConfig.class);
- }
-
- @Test
- public void qualifiedStringBeanInjection() {
- new AnnotationConfigApplicationContext(StringBeanSubConfig.class, StringBeanInjectionByQualifierFeatureConfig.class);
- }
-
-
- @FeatureConfiguration
- static class SpelValueInjectionFeatureConfig {
- @Feature
- public StubSpecification feature(@Value("#{environment['foo']}") String foo) {
- return new StubSpecification();
- }
- }
-
-
- @FeatureConfiguration
- static class SpelIntValueInjectionFeatureConfig {
- @Feature
- public StubSpecification feature(@Value("#{environment['num']}") int num) {
- assertThat(num, is(5));
- return new StubSpecification();
- }
- }
-
-
- @Configuration
- static class StringBeanConfig {
- @Bean
- public String stringBean() {
- return "sb";
- }
- }
-
-
- @Configuration
- static class StringBeanSubConfig extends StringBeanConfig {
- @Bean
- public String stringBean2() {
- return "sb2";
- }
- }
-
-
- @FeatureConfiguration
- static class StringBeanInjectionByTypeFeatureConfig {
- @Feature
- public StubSpecification feature(String string) {
- assertThat(string, is("sb"));
- return new StubSpecification();
- }
- }
-
-
- @FeatureConfiguration
- static class StringBeanInjectionByQualifierFeatureConfig {
- @Feature
- public StubSpecification feature(@Qualifier("stringBean2") String string) {
- assertThat(string, is("sb2"));
- return new StubSpecification();
- }
- }
-
-
- @Configuration
- static class Config {
- @Value("#{environment['foo']}") String foo;
- @Value("#{environment['num']}") int num;
- }
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/SimpleFeatureMethodProcessingTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/SimpleFeatureMethodProcessingTests.java
deleted file mode 100644
index 247263a1a06..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/SimpleFeatureMethodProcessingTests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.springframework.context.annotation.configuration.StubSpecification;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.util.Assert;
-
-/**
- * Simple tests to ensure that @Feature methods are invoked and that the
- * resulting returned {@link FeatureSpecification} object is delegated to
- * the correct {@link FeatureSpecificationExecutor}.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class SimpleFeatureMethodProcessingTests {
-
- @Test
- public void test() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(FeatureConfig.class);
- assertThat(MySpecificationExecutor.executeMethodWasCalled, is(false));
- ctx.refresh();
- assertThat(MySpecificationExecutor.executeMethodWasCalled, is(true));
- }
-
- @FeatureConfiguration
- static class FeatureConfig {
- @Feature
- public FeatureSpecification f() {
- return new StubSpecification(MySpecificationExecutor.class);
- }
- }
-
- static class MySpecificationExecutor implements FeatureSpecificationExecutor {
- static boolean executeMethodWasCalled = false;
- public void execute(FeatureSpecification spec, SpecificationContext specificationContext) {
- Assert.state(executeMethodWasCalled == false);
- executeMethodWasCalled = true;
- }
- }
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodAndAutowiredFieldTests.xml b/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodAndAutowiredFieldTests.xml
deleted file mode 100644
index 0418dc8251a..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodAndAutowiredFieldTests.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodLifecycleIssueTestSuite.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodLifecycleIssueTestSuite.java
deleted file mode 100644
index 9c057cceb0b..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/FeatureMethodLifecycleIssueTestSuite.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation.configuration;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-import org.springframework.context.annotation.FeatureMethodEarlyBeanProxyTests;
-
-/**
- * Test suite that groups all tests related to @Feature method lifecycle issues.
- *
- * @author Chris Beams
- */
-@RunWith(Suite.class)
-@SuiteClasses({
- FeatureMethodEarlyBeanProxyTests.class,
- ConfigurationClassWithPlaceholderConfigurerBeanTests.class
-})
-public class FeatureMethodLifecycleIssueTestSuite {
-
-}
diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/StubSpecification.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/StubSpecification.java
deleted file mode 100644
index 53ed3dad757..00000000000
--- a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/StubSpecification.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation.configuration;
-
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-
-public class StubSpecification extends AbstractFeatureSpecification {
-
- public StubSpecification() {
- this(StubSpecificationExecutor.class);
- }
-
- public StubSpecification(Class extends FeatureSpecificationExecutor> excecutorType) {
- super(excecutorType);
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- }
-
-}
-
-class StubSpecificationExecutor implements FeatureSpecificationExecutor {
-
- public void execute(FeatureSpecification spec, SpecificationContext specificationContext) {
- }
-
-}
diff --git a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java b/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java
deleted file mode 100644
index 5531b325d2c..00000000000
--- a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.context.annotation;
-
-/**
- * Tests directly or indirectly related to {@link FeatureConfiguration} class and
- * {@link Feature} method processing.
- *
- * @author Chris Beams
- * @since 3.1
- *
- * commented due to classpath visibility differences between Eclipse
- * and Ant/Ivy at the command line. Eclipse can see classes across
- * project test folders, Ant/Ivy are not configured to do so. Uncomment
- * as necessary when doing @Feature-related work.
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-import org.springframework.transaction.TxNamespaceHandlerTests;
-import org.springframework.transaction.annotation.AnnotationTransactionNamespaceHandlerTests;
-import org.springframework.transaction.annotation.TxAnnotationDrivenFeatureTests;
-import org.springframework.transaction.config.AnnotationDrivenTests;
-import org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParserTests;
-import org.springframework.web.servlet.config.MvcAnnotationDrivenFeatureTests;
-import org.springframework.web.servlet.config.MvcDefaultServletHandlerTests;
-import org.springframework.web.servlet.config.MvcNamespaceTests;
-import org.springframework.web.servlet.config.MvcResourcesTests;
-import org.springframework.web.servlet.config.MvcViewControllersTests;
-
-@RunWith(Suite.class)
-@SuiteClasses({
- EarlyBeanReferenceProxyCreatorTests.class,
- SimpleFeatureMethodProcessingTests.class,
- BeanFactoryAwareFeatureConfigurationTests.class,
- FeatureMethodBeanReferenceTests.class,
- FeatureMethodQualifiedBeanReferenceTests.class,
- FeatureMethodErrorTests.class,
- FeatureConfigurationClassTests.class,
- FeatureMethodEarlyBeanProxyTests.class,
- FeatureConfigurationImportTests.class,
- FeatureConfigurationImportResourceTests.class,
-
- // context:component-scan related
- ComponentScanFeatureTests.class,
- ComponentScanSpecTests.class,
- ComponentScanAnnotationTests.class,
- ComponentScanAnnotationIntegrationTests.class,
-
- // tx-related
- TxAnnotationDrivenFeatureTests.class,
- TxNamespaceHandlerTests.class,
- AnnotationTransactionNamespaceHandlerTests.class,
- AnnotationDrivenTests.class,
-
- // mvc-related
- AnnotationDrivenBeanDefinitionParserTests.class,
- MvcAnnotationDrivenFeatureTests.class,
- MvcViewControllersTests.class,
- MvcResourcesTests.class,
- MvcDefaultServletHandlerTests.class,
- MvcNamespaceTests.class
-})
-*/
-public class FeatureTestSuite {
-
-}
\ No newline at end of file
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
index f4b1de641d7..f226115b6d3 100644
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
+++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
@@ -16,7 +16,15 @@
package org.springframework.transaction.config;
+import org.w3c.dom.Element;
+
import org.springframework.aop.config.AopNamespaceUtils;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
import org.springframework.context.config.FeatureSpecification;
@@ -40,7 +48,7 @@ import org.w3c.dom.Element;
* @since 2.0
* @see TxAnnotationDriven
*/
-class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
/**
* The bean name of the internally managed transaction advisor (mode="proxy").
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java
index fbc190e4935..f90ca8b6b77 100644
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java
+++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * 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.
@@ -31,7 +31,7 @@ import org.springframework.util.ClassUtils;
* @author Christian Dupuis
* @since 2.5
*/
-class JtaTransactionManagerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
+public class JtaTransactionManagerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
private static final String WEBLOGIC_JTA_TRANSACTION_MANAGER_CLASS_NAME =
"org.springframework.transaction.jta.WebLogicJtaTransactionManager";
@@ -74,7 +74,7 @@ class JtaTransactionManagerBeanDefinitionParser extends AbstractSingleBeanDefini
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
- return TxAnnotationDriven.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME;
+ return TxNamespaceHandler.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME;
}
}
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAdviceBeanDefinitionParser.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAdviceBeanDefinitionParser.java
index a8a88ca5993..7883b719e9d 100644
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAdviceBeanDefinitionParser.java
+++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAdviceBeanDefinitionParser.java
@@ -48,8 +48,6 @@ import org.springframework.util.xml.DomUtils;
*/
class TxAdviceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
- private static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
-
private static final String METHOD_ELEMENT = "method";
private static final String METHOD_NAME_ATTRIBUTE = "name";
@@ -76,7 +74,7 @@ class TxAdviceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
- builder.addPropertyReference("transactionManager", element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE));
+ builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element));
List txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT);
if (txAttributes.size() > 1) {
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDriven.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDriven.java
deleted file mode 100644
index 29bacea94f4..00000000000
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDriven.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.transaction.config;
-
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.AdviceMode;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.Assert;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-public final class TxAnnotationDriven extends AbstractFeatureSpecification {
-
- static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = TxAnnotationDrivenExecutor.class;
-
- private Object txManager = null;
-
- private Object order = null;
-
- private Boolean proxyTargetClass = false;
-
- private Object mode = AdviceMode.PROXY;
-
- /**
- * Create a {@code TxAnnotationDriven} specification assumes the presence of a
- * {@link PlatformTransactionManager} bean named {@value #DEFAULT_TRANSACTION_MANAGER_BEAN_NAME}.
- *
- * See the alternate constructors defined here if your transaction manager does
- * not follow this default naming or you wish to refer to it by bean instance rather
- * than by bean name.
- * @see #TxAnnotationDriven(String)
- * @see #TxAnnotationDriven(PlatformTransactionManager)
- */
- public TxAnnotationDriven() {
- this(DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
- }
-
- /**
- * Create a new {@code TxAnnotationDriven} specification that will use the specified
- * transaction manager bean name.
- *
- * @param txManagerBeanName name of {@link PlatformTransactionManager} bean or a
- * ${placeholder} or SpEL #{expression} resolving to bean name. If {@code null},
- * falls back to default value of {@value #DEFAULT_TRANSACTION_MANAGER_BEAN_NAME}.
- */
- public TxAnnotationDriven(String txManagerBeanName) {
- super(EXECUTOR_TYPE);
- this.txManager = txManagerBeanName != null ?
- txManagerBeanName :
- DEFAULT_TRANSACTION_MANAGER_BEAN_NAME;
- }
-
- /**
- * Create a new TxAnnotationDriven specification that will use the specified transaction
- * manager.
- *
- * @param txManager the {@link PlatformTransactionManager} bean to use. Must not be {@code null}.
- */
- public TxAnnotationDriven(PlatformTransactionManager txManager) {
- super(EXECUTOR_TYPE);
- Assert.notNull(txManager, "transaction manager must not be null");
- this.txManager = txManager;
- }
-
- /**
- * Return the transaction manager to use. May be a {@link PlatformTransactionManager}
- * instance or a String representing the bean name or a placeholder or SpEL expression
- * that resolves to the bean name.
- */
- Object transactionManager() {
- return this.txManager;
- }
-
- /**
- * Indicate how transactional advice should be applied.
- * @see AdviceMode
- */
- public TxAnnotationDriven mode(AdviceMode mode) {
- this.mode = mode;
- return this;
- }
-
- /**
- * Indicate how transactional advice should be applied.
- * @param name matching one of the labels in the AdviceMode enum;
- * placeholder and SpEL expressions are not allowed.
- * @see AdviceMode
- */
- TxAnnotationDriven mode(String mode) {
- if (StringUtils.hasText(mode)) {
- this.mode = mode;
- }
- return this;
- }
-
- /**
- * Return how transactional advice should be applied.
- */
- AdviceMode mode() {
- if (this.mode instanceof AdviceMode) {
- return (AdviceMode)this.mode;
- }
- if (this.mode instanceof String) {
- return ObjectUtils.caseInsensitiveValueOf(AdviceMode.values(), (String)this.mode);
- }
- // TODO SPR-7420: deal with in validate & raise problem
- throw new IllegalStateException(
- "invalid type for field 'mode' (must be of type AdviceMode or String): "
- + this.mode.getClass().getName());
- }
-
- /**
- * Indicate whether class-based (CGLIB) proxies are to be created as opposed
- * to standard Java interface-based proxies.
- *
- *
Note: Class-based proxies require the {@link Transactional @Transactional}
- * annotation to be defined on the concrete class. Annotations in interfaces will
- * not work in that case (they will rather only work with interface-based proxies)!
- */
- public TxAnnotationDriven proxyTargetClass(Boolean proxyTargetClass) {
- this.proxyTargetClass = proxyTargetClass;
- return this;
- }
-
- /**
- * Return whether class-based (CGLIB) proxies are to be created as opposed
- * to standard Java interface-based proxies.
- */
- Boolean proxyTargetClass() {
- return this.proxyTargetClass;
- }
-
- /**
- * Indicate the ordering of the execution of the transaction advisor
- * when multiple advice executes at a specific joinpoint. The default is
- * {@code null}, indicating that default ordering should be used.
- */
- public TxAnnotationDriven order(int order) {
- this.order = order;
- return this;
- }
-
- /**
- * Indicate the ordering of the execution of the transaction advisor
- * when multiple advice executes at a specific joinpoint. The default is
- * {@code null}, indicating that default ordering should be used.
- */
- public TxAnnotationDriven order(String order) {
- if (StringUtils.hasText(order)) {
- this.order = order;
- }
- return this;
- }
-
- /**
- * Return the ordering of the execution of the transaction advisor
- * when multiple advice executes at a specific joinpoint. May return
- * {@code null}, indicating that default ordering should be used.
- */
- Object order() {
- return this.order;
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- if (this.mode instanceof String) {
- if (!ObjectUtils.containsConstant(AdviceMode.values(), (String)this.mode)) {
- problems.error("no such mode name: " + this.mode);
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDrivenExecutor.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDrivenExecutor.java
deleted file mode 100644
index c4f328986ed..00000000000
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxAnnotationDrivenExecutor.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.transaction.config;
-
-import org.springframework.aop.config.AopNamespaceUtils;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
-import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
-import org.springframework.util.Assert;
-
-/**
- * TODO SPR-7420: document
- *
- * @author Chris Beams
- * @since 3.1
- */
-final class TxAnnotationDrivenExecutor extends AbstractSpecificationExecutor {
-
- /**
- * The bean name of the internally managed transaction advisor (used when mode == PROXY).
- */
- public static final String TRANSACTION_ADVISOR_BEAN_NAME =
- "org.springframework.transaction.config.internalTransactionAdvisor";
-
- /**
- * The bean name of the internally managed transaction aspect (used when mode == ASPECTJ).
- */
- public static final String TRANSACTION_ASPECT_BEAN_NAME =
- "org.springframework.transaction.config.internalTransactionAspect";
-
- private static final String TRANSACTION_ASPECT_CLASS_NAME =
- "org.springframework.transaction.aspectj.AnnotationTransactionAspect";
-
-
- @Override
- protected void doExecute(TxAnnotationDriven txSpec, SpecificationContext specificationContext) {
- BeanDefinitionRegistry registry = specificationContext.getRegistry();
- ComponentRegistrar registrar = specificationContext.getRegistrar();
- switch (txSpec.mode()) {
- case ASPECTJ:
- registerTransactionAspect(txSpec, registry, registrar);
- break;
- case PROXY:
- AopAutoProxyConfigurer.configureAutoProxyCreator(txSpec, registry, registrar);
- break;
- default:
- throw new IllegalArgumentException(
- String.format("AdviceMode %s is not supported", txSpec.mode()));
- }
- }
-
- private void registerTransactionAspect(TxAnnotationDriven spec, BeanDefinitionRegistry registry, ComponentRegistrar registrar) {
- if (!registry.containsBeanDefinition(TRANSACTION_ASPECT_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition();
- def.setBeanClassName(TRANSACTION_ASPECT_CLASS_NAME);
- def.setFactoryMethodName("aspectOf");
- registerTransactionManager(spec, def);
- registrar.registerBeanComponent(new BeanComponentDefinition(def, TRANSACTION_ASPECT_BEAN_NAME));
- }
- }
-
- private static void registerTransactionManager(TxAnnotationDriven spec, BeanDefinition def) {
- Object txManager = spec.transactionManager();
- Assert.notNull(txManager, "transactionManager must be specified");
- if (txManager instanceof String) {
- def.getPropertyValues().add("transactionManagerBeanName", txManager);
- } else {
- def.getPropertyValues().add("transactionManager", txManager);
- }
- }
-
- /**
- * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
- */
- private static class AopAutoProxyConfigurer {
-
- public static void configureAutoProxyCreator(TxAnnotationDriven txSpec, BeanDefinitionRegistry registry, ComponentRegistrar registrar) {
- Object source = txSpec.source();
- AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(registry, registrar, source, txSpec.proxyTargetClass());
-
- if (!registry.containsBeanDefinition(TRANSACTION_ADVISOR_BEAN_NAME)) {
-
- // Create the TransactionAttributeSource definition.
- RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class);
- sourceDef.setSource(source);
- sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- String sourceName = registrar.registerWithGeneratedName(sourceDef);
-
- // Create the TransactionInterceptor definition.
- RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
- interceptorDef.setSource(source);
- interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- registerTransactionManager(txSpec, interceptorDef);
- interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
- String interceptorName = registrar.registerWithGeneratedName(interceptorDef);
-
- // Create the TransactionAttributeSourceAdvisor definition.
- RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
- advisorDef.setSource(source);
- advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
- advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
- if (txSpec.order() != null) {
- advisorDef.getPropertyValues().add("order", txSpec.order());
- }
- registry.registerBeanDefinition(TRANSACTION_ADVISOR_BEAN_NAME, advisorDef);
-
- CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(txSpec.sourceName(), source);
- compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
- compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
- compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, TRANSACTION_ADVISOR_BEAN_NAME));
- registrar.registerComponent(compositeDef);
- }
- }
- }
-}
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxNamespaceHandler.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxNamespaceHandler.java
index bdf376f2473..ac657898304 100644
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxNamespaceHandler.java
+++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/TxNamespaceHandler.java
@@ -39,6 +39,17 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
*/
public class TxNamespaceHandler extends NamespaceHandlerSupport {
+ static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
+
+ static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
+
+
+ static String getTransactionManagerName(Element element) {
+ return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
+ element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
+ }
+
+
public void init() {
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
diff --git a/org.springframework.transaction/src/test/java/org/springframework/transaction/annotation/TxAnnotationDrivenFeatureTests.java b/org.springframework.transaction/src/test/java/org/springframework/transaction/annotation/TxAnnotationDrivenFeatureTests.java
deleted file mode 100644
index 7071426d260..00000000000
--- a/org.springframework.transaction/src/test/java/org/springframework/transaction/annotation/TxAnnotationDrivenFeatureTests.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.transaction.annotation;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.CannotLoadBeanClassException;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.context.config.AdviceMode;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.CallCountingTransactionManager;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.AnnotationTransactionNamespaceHandlerTests.TransactionalTestBean;
-import org.springframework.transaction.config.TxAnnotationDriven;
-
-/**
- * Integration tests for {@link TxAnnotationDriven} support within @Configuration
- * classes. Adapted from original tx: namespace tests at
- * {@link AnnotationTransactionNamespaceHandlerTests}.
- *
- * @author Chris Beams
- * @since 3.1
- */
-public class TxAnnotationDrivenFeatureTests {
- @Test
- public void transactionProxyIsCreated() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(TxFeature.class, TxManagerConfig.class);
- ctx.refresh();
- TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
- assertThat("testBean is not a proxy", AopUtils.isAopProxy(bean), is(true));
- Map,?> services = ctx.getBeansWithAnnotation(Service.class);
- assertThat("Stereotype annotation not visible", services.containsKey("testBean"), is(true));
- }
-
- @Test
- public void txManagerIsResolvedOnInvocationOfTransactionalMethod() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(TxFeature.class, TxManagerConfig.class);
- ctx.refresh();
- TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
-
- // invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
- bean.findAllFoos();
- }
-
- @Test
- public void txManagerIsResolvedCorrectlyWhenMultipleManagersArePresent() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(TxFeature.class, MultiTxManagerConfig.class);
- ctx.refresh();
- TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
-
- // invoke a transactional method, causing the PlatformTransactionManager bean to be resolved.
- bean.findAllFoos();
- }
-
- /**
- * A cheap test just to prove that in ASPECTJ mode, the AnnotationTransactionAspect does indeed
- * get loaded -- or in this case, attempted to be loaded at which point the test fails.
- */
- @Test
- public void proxyTypeAspectJCausesRegistrationOfAnnotationTransactionAspect() {
- try {
- new AnnotationConfigApplicationContext(TxWithAspectJFeature.class, TxManagerConfig.class);
- fail("should have thrown CNFE when trying to load AnnotationTransactionAspect. " +
- "Do you actually have org.springframework.aspects on the classpath?");
- } catch (CannotLoadBeanClassException ex) {
- ClassNotFoundException cause = (ClassNotFoundException) ex.getCause();
- assertThat(cause.getMessage(), equalTo("org.springframework.transaction.aspectj.AnnotationTransactionAspect"));
- }
- }
-
-}
-
-@FeatureConfiguration
-class TxFeature {
-
- @Feature
- public TxAnnotationDriven tx(TxManagerConfig txManagerConfig) {
- return new TxAnnotationDriven(txManagerConfig.txManager());
- }
-}
-
-
-@FeatureConfiguration
-class TxWithAspectJFeature {
-
- @Feature
- public TxAnnotationDriven tx(PlatformTransactionManager txManager) {
- return new TxAnnotationDriven(txManager).mode(AdviceMode.ASPECTJ);
- }
-
-}
-
-
-@Configuration
-class TxManagerConfig {
-
- @Bean
- public TransactionalTestBean testBean() {
- return new TransactionalTestBean();
- }
-
- @Bean
- public PlatformTransactionManager txManager() {
- return new CallCountingTransactionManager();
- }
-
-}
-
-
-@Configuration
-class MultiTxManagerConfig extends TxManagerConfig {
-
- @Bean
- public PlatformTransactionManager txManager2() {
- return new CallCountingTransactionManager();
- }
-
-}
-
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AbstractHttpRequestHandlerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AbstractHttpRequestHandlerBeanDefinitionParser.java
new file mode 100644
index 00000000000..13f10cf673b
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AbstractHttpRequestHandlerBeanDefinitionParser.java
@@ -0,0 +1,57 @@
+/*
+ * 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.web.servlet.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
+
+/**
+ * Abstract base class for {@link BeanDefinitonParser}s that register an HttpRequestHandler.
+ *
+ * @author Jeremy Grelle
+ * @since 3.0.4
+ */
+abstract class AbstractHttpRequestHandlerBeanDefinitionParser implements BeanDefinitionParser{
+
+ private static final String HANDLER_ADAPTER_BEAN_NAME = "org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter";
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+ registerHandlerAdapterIfNecessary(parserContext, source);
+ doParse(element, parserContext);
+ return null;
+ }
+
+ public abstract void doParse(Element element, ParserContext parserContext);
+
+ private void registerHandlerAdapterIfNecessary(ParserContext parserContext, Object source) {
+ if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_ADAPTER_BEAN_NAME)) {
+ RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
+ handlerAdapterDef.setSource(source);
+ handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ parserContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
+ parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
+ }
+ }
+
+}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
index ad4885a8453..ebfb201dc32 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 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,65 +16,265 @@
package org.springframework.web.servlet.config;
-import java.util.ArrayList;
import java.util.List;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.format.support.FormattingConversionServiceFactoryBean;
+import org.springframework.http.converter.ByteArrayHttpMessageConverter;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.ResourceHttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
+import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
+import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
+import org.springframework.http.converter.xml.SourceHttpMessageConverter;
+import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
import org.springframework.util.ClassUtils;
import org.springframework.util.xml.DomUtils;
+import org.springframework.validation.Validator;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.WebArgumentResolver;
+import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
+import org.springframework.web.servlet.handler.MappedInterceptor;
+import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
-import org.w3c.dom.Element;
+import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
/**
- * {@link BeanDefinitionParser} that parses the {@code annotation-driven} element
- * to configure a Spring MVC web application.
+ * {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web
+ * application.
*
+ * Responsible for:
+ *
+ * Registering a DefaultAnnotationHandlerMapping bean for mapping HTTP Servlet Requests to @Controller methods
+ * using @RequestMapping annotations.
+ * Registering a AnnotationMethodHandlerAdapter bean for invoking annotated @Controller methods.
+ * Will configure the HandlerAdapter's webBindingInitializer property for centrally configuring
+ * {@code @Controller} {@code DataBinder} instances:
+ *
+ * Configures the conversionService if specified, otherwise defaults to a fresh {@link ConversionService} instance
+ * created by the default {@link FormattingConversionServiceFactoryBean}.
+ * Configures the validator if specified, otherwise defaults to a fresh {@link Validator} instance created by the
+ * default {@link LocalValidatorFactoryBean} if the JSR-303 API is present on the classpath .
+ * Configures standard {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters},
+ * including the {@link Jaxb2RootElementHttpMessageConverter} if JAXB2 is present on the classpath , and
+ * the {@link MappingJacksonHttpMessageConverter} if Jackson is present on the classpath .
+ *
+ *
+ *
+ * @author Keith Donald
+ * @author Juergen Hoeller
+ * @author Arjen Poutsma
* @author Rossen Stoyanchev
- * @author Chris Beams
* @since 3.0
- * @see MvcAnnotationDriven
- * @see MvcAnnotationDrivenExecutor
*/
-class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
- /**
- * Parses the {@code } tag.
- */
- @Override
- protected FeatureSpecification doParse(Element element, ParserContext parserContext) {
- MvcAnnotationDriven spec = new MvcAnnotationDriven();
+ private static final boolean jsr303Present = ClassUtils.isPresent(
+ "javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
+
+ private static final boolean jaxb2Present =
+ ClassUtils.isPresent("javax.xml.bind.Binder", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
+
+ private static final boolean jacksonPresent =
+ ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()) &&
+ ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
+
+ private static boolean romePresent =
+ ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
+
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+
+ CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
+ parserContext.pushContainingComponent(compDefinition);
+
+ RootBeanDefinition methodMappingDef = new RootBeanDefinition(RequestMappingHandlerMethodMapping.class);
+ methodMappingDef.setSource(source);
+ methodMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ methodMappingDef.getPropertyValues().add("order", 0);
+ String methodMappingName = parserContext.getReaderContext().registerWithGeneratedName(methodMappingDef);
+
+ RuntimeBeanReference conversionService = getConversionService(element, source, parserContext);
+ RuntimeBeanReference validator = getValidator(element, source, parserContext);
+ RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element, source, parserContext);
+
+ RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
+ bindingDef.setSource(source);
+ bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ bindingDef.getPropertyValues().add("conversionService", conversionService);
+ bindingDef.getPropertyValues().add("validator", validator);
+ bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);
+
+ ManagedList> messageConverters = getMessageConverters(element, source, parserContext);
+ ManagedList> argumentResolvers = getArgumentResolvers(element, source, parserContext);
+
+ RootBeanDefinition methodAdapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class);
+ methodAdapterDef.setSource(source);
+ methodAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ methodAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
+ methodAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
+ if (argumentResolvers != null) {
+ methodAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
+ }
+ String methodAdapterName = parserContext.getReaderContext().registerWithGeneratedName(methodAdapterDef);
+
+ RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
+ csInterceptorDef.setSource(source);
+ csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
+ RootBeanDefinition mappedCsInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
+ mappedCsInterceptorDef.setSource(source);
+ mappedCsInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
+ mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
+ String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef);
+
+ RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(RequestMappingHandlerMethodExceptionResolver.class);
+ methodExceptionResolver.setSource(source);
+ methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
+ methodExceptionResolver.getPropertyValues().add("order", 0);
+ String methodExceptionResolverName =
+ parserContext.getReaderContext().registerWithGeneratedName(methodExceptionResolver);
+
+ RootBeanDefinition responseStatusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
+ responseStatusExceptionResolver.setSource(source);
+ responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ responseStatusExceptionResolver.getPropertyValues().add("order", 1);
+ String responseStatusExceptionResolverName =
+ parserContext.getReaderContext().registerWithGeneratedName(responseStatusExceptionResolver);
+
+ RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
+ defaultExceptionResolver.setSource(source);
+ defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ defaultExceptionResolver.getPropertyValues().add("order", 2);
+ String defaultExceptionResolverName =
+ parserContext.getReaderContext().registerWithGeneratedName(defaultExceptionResolver);
+
+ parserContext.registerComponent(new BeanComponentDefinition(methodMappingDef, methodMappingName));
+ parserContext.registerComponent(new BeanComponentDefinition(methodAdapterDef, methodAdapterName));
+ parserContext.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExceptionResolverName));
+ parserContext.registerComponent(new BeanComponentDefinition(responseStatusExceptionResolver, responseStatusExceptionResolverName));
+ parserContext.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExceptionResolverName));
+ parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));
+ parserContext.popAndRegisterContainingComponent();
+
+ return null;
+ }
+
+ private RuntimeBeanReference getConversionService(Element element, Object source, ParserContext parserContext) {
+ RuntimeBeanReference conversionServiceRef;
if (element.hasAttribute("conversion-service")) {
- String conversionService = element.getAttribute("conversion-service");
- spec.conversionService(conversionService);
+ conversionServiceRef = new RuntimeBeanReference(element.getAttribute("conversion-service"));
}
+ else {
+ RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);
+ conversionDef.setSource(source);
+ conversionDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ String conversionName = parserContext.getReaderContext().registerWithGeneratedName(conversionDef);
+ parserContext.registerComponent(new BeanComponentDefinition(conversionDef, conversionName));
+ conversionServiceRef = new RuntimeBeanReference(conversionName);
+ }
+ return conversionServiceRef;
+ }
+
+ private RuntimeBeanReference getValidator(Element element, Object source, ParserContext parserContext) {
if (element.hasAttribute("validator")) {
- spec.validator(element.getAttribute("validator"));
+ return new RuntimeBeanReference(element.getAttribute("validator"));
}
+ else if (jsr303Present) {
+ RootBeanDefinition validatorDef = new RootBeanDefinition(LocalValidatorFactoryBean.class);
+ validatorDef.setSource(source);
+ validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
+ parserContext.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
+ return new RuntimeBeanReference(validatorName);
+ }
+ else {
+ return null;
+ }
+ }
+
+ private RuntimeBeanReference getMessageCodesResolver(Element element, Object source, ParserContext parserContext) {
if (element.hasAttribute("message-codes-resolver")) {
- spec.messageCodesResolver(element.getAttribute("message-codes-resolver"));
- }
- Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
- if (convertersElement != null) {
- if (convertersElement.hasAttribute("register-defaults")) {
- spec.shouldRegisterDefaultMessageConverters(Boolean.valueOf(convertersElement
- .getAttribute("register-defaults")));
- }
- spec.messageConverters(extractBeanSubElements(convertersElement, parserContext));
+ return new RuntimeBeanReference(element.getAttribute("message-codes-resolver"));
+ } else {
+ return null;
}
+ }
+
+ private ManagedList> getArgumentResolvers(Element element, Object source, ParserContext parserContext) {
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
if (resolversElement != null) {
- ManagedList beanDefs = extractBeanSubElements(resolversElement, parserContext);
- spec.argumentResolvers(wrapWebArgumentResolverBeanDefs(beanDefs));
+ ManagedList argumentResolvers = extractBeanSubElements(resolversElement, parserContext);
+ return wrapWebArgumentResolverBeanDefs(argumentResolvers);
+ }
+ return null;
+ }
+
+ private ManagedList> getMessageConverters(Element element, Object source, ParserContext parserContext) {
+ Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
+ ManagedList super Object> messageConverters = new ManagedList();
+ if (convertersElement != null) {
+ messageConverters.setSource(source);
+ for (Element converter : DomUtils.getChildElementsByTagName(convertersElement, "bean")) {
+ BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(converter);
+ beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(converter, beanDef);
+ messageConverters.add(beanDef);
+ }
}
- return spec;
+ if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
+ messageConverters.setSource(source);
+ messageConverters.add(createConverterBeanDefinition(ByteArrayHttpMessageConverter.class, source));
+
+ RootBeanDefinition stringConverterDef = createConverterBeanDefinition(StringHttpMessageConverter.class,
+ source);
+ stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
+ messageConverters.add(stringConverterDef);
+
+ messageConverters.add(createConverterBeanDefinition(ResourceHttpMessageConverter.class, source));
+ messageConverters.add(createConverterBeanDefinition(SourceHttpMessageConverter.class, source));
+ messageConverters.add(createConverterBeanDefinition(XmlAwareFormHttpMessageConverter.class, source));
+ if (jaxb2Present) {
+ messageConverters
+ .add(createConverterBeanDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
+ }
+ if (jacksonPresent) {
+ messageConverters.add(createConverterBeanDefinition(MappingJacksonHttpMessageConverter.class, source));
+ }
+ if (romePresent) {
+ messageConverters.add(createConverterBeanDefinition(AtomFeedHttpMessageConverter.class, source));
+ messageConverters.add(createConverterBeanDefinition(RssChannelHttpMessageConverter.class, source));
+ }
+ }
+ return messageConverters;
+ }
+
+ private RootBeanDefinition createConverterBeanDefinition(Class extends HttpMessageConverter> converterClass,
+ Object source) {
+ RootBeanDefinition beanDefinition = new RootBeanDefinition(converterClass);
+ beanDefinition.setSource(source);
+ beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+
+ return beanDefinition;
}
private ManagedList extractBeanSubElements(Element parentElement, ParserContext parserContext) {
@@ -90,21 +290,20 @@ class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefi
private ManagedList wrapWebArgumentResolverBeanDefs(List beanDefs) {
ManagedList result = new ManagedList();
-
+
for (BeanDefinitionHolder beanDef : beanDefs) {
String className = beanDef.getBeanDefinition().getBeanClassName();
Class> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
-
+
if (WebArgumentResolver.class.isAssignableFrom(clazz)) {
RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class);
adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef);
result.add(new BeanDefinitionHolder(adapter, beanDef.getBeanName() + "Adapter"));
- }
- else {
+ } else {
result.add(beanDef);
}
}
-
+
return result;
}
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java
index 7efa18b5bcb..fe60722234d 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java
@@ -16,36 +16,58 @@
package org.springframework.web.servlet.config;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
-import org.w3c.dom.Element;
/**
* {@link BeanDefinitionParser} that parses a {@code default-servlet-handler} element to
* register a {@link DefaultServletHttpRequestHandler}. Will also register a
* {@link SimpleUrlHandlerMapping} for mapping resource requests, and a
* {@link HttpRequestHandlerAdapter} if necessary.
- *
- * @author Rossen Stoyanchev
- * @author Chris Beams
+ *
+ * @author Jeremy Grelle
* @since 3.0.4
*/
-class DefaultServletHandlerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+class DefaultServletHandlerBeanDefinitionParser extends AbstractHttpRequestHandlerBeanDefinitionParser {
- /**
- * Parses the {@code } tag.
- */
- public FeatureSpecification doParse(Element element, ParserContext parserContext) {
- String defaultServletHandler = element.getAttribute("default-servlet-handler");
- return StringUtils.hasText(defaultServletHandler) ?
- new MvcDefaultServletHandler(defaultServletHandler) :
- new MvcDefaultServletHandler();
+ @Override
+ public void doParse(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+
+ String defaultServletName = element.getAttribute("default-servlet-name");
+ RootBeanDefinition defaultServletHandlerDef = new RootBeanDefinition(DefaultServletHttpRequestHandler.class);
+ defaultServletHandlerDef.setSource(source);
+ defaultServletHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ if (StringUtils.hasText(defaultServletName)) {
+ defaultServletHandlerDef.getPropertyValues().add("defaultServletName", defaultServletName);
+ }
+ String defaultServletHandlerName = parserContext.getReaderContext().generateBeanName(defaultServletHandlerDef);
+ parserContext.getRegistry().registerBeanDefinition(defaultServletHandlerName, defaultServletHandlerDef);
+ parserContext.registerComponent(new BeanComponentDefinition(defaultServletHandlerDef, defaultServletHandlerName));
+
+ Map urlMap = new ManagedMap();
+ urlMap.put("/**", defaultServletHandlerName);
+
+ RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
+ handlerMappingDef.setSource(source);
+ handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
+
+ String handlerMappingBeanName = parserContext.getReaderContext().generateBeanName(handlerMappingDef);
+ parserContext.getRegistry().registerBeanDefinition(handlerMappingBeanName, handlerMappingDef);
+ parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingBeanName));
}
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java
index 55f95bb9e6f..90a3afebff0 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java
@@ -18,54 +18,59 @@ package org.springframework.web.servlet.config;
import java.util.List;
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
import org.springframework.util.xml.DomUtils;
import org.springframework.web.servlet.handler.MappedInterceptor;
import org.w3c.dom.Element;
/**
- * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses
- * a {@code interceptors} element to register set of {@link MappedInterceptor}
- * definitions.
+ * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a {@code interceptors} element to register
+ * a set of {@link MappedInterceptor} definitions.
*
* @author Keith Donald
- * @author Rossen Stoyanchev
- *
* @since 3.0
*/
-class InterceptorsBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
-
- /**
- * Parses the {@code } tag.
- */
- public FeatureSpecification doParse(Element element, ParserContext parserContext) {
- MvcInterceptors mvcInterceptors = new MvcInterceptors();
+class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
+ parserContext.pushContainingComponent(compDefinition);
+
List interceptors = DomUtils.getChildElementsByTagName(element, new String[] { "bean", "interceptor" });
for (Element interceptor : interceptors) {
+ RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
+ mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));
+ mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ String[] pathPatterns;
+ BeanDefinitionHolder interceptorDef;
if ("interceptor".equals(interceptor.getLocalName())) {
List paths = DomUtils.getChildElementsByTagName(interceptor, "mapping");
- String[] pathPatterns = new String[paths.size()];
+ pathPatterns = new String[paths.size()];
for (int i = 0; i < paths.size(); i++) {
pathPatterns[i] = paths.get(i).getAttribute("path");
}
- Element beanElement = DomUtils.getChildElementByTagName(interceptor, "bean");
- mvcInterceptors.interceptor(pathPatterns, parseBeanElement(parserContext, beanElement));
+ Element interceptorBean = DomUtils.getChildElementByTagName(interceptor, "bean");
+ interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(interceptorBean);
+ interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptorBean, interceptorDef);
} else {
- mvcInterceptors.interceptor(null, parseBeanElement(parserContext, interceptor));
+ pathPatterns = null;
+ interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(interceptor);
+ interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptor, interceptorDef);
}
+ mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, pathPatterns);
+ mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, interceptorDef);
+ String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
+ parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
}
-
- return mvcInterceptors;
+
+ parserContext.popAndRegisterContainingComponent();
+ return null;
}
-
- private BeanDefinitionHolder parseBeanElement(ParserContext parserContext, Element interceptor) {
- BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(interceptor);
- beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptor, beanDef);
- return beanDef;
- }
-
+
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java
deleted file mode 100644
index 641327df1ec..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.core.convert.ConversionService;
-import org.springframework.format.support.FormattingConversionServiceFactoryBean;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
-import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
-import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
-import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
-import org.springframework.validation.MessageCodesResolver;
-import org.springframework.validation.Validator;
-import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
-import org.springframework.web.bind.support.WebArgumentResolver;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
-
-/**
- * Specifies the Spring MVC "annotation-driven" container feature. The
- * feature provides the following fine-grained configuration:
- *
- *
- * {@code DefaultAnnotationHandlerMapping} bean for mapping HTTP Servlet Requests
- * to {@code @Controller} methods using {@code @RequestMapping} annotations.
- * {@code AnnotationMethodHandlerAdapter} bean for invoking annotated
- * {@code @Controller} methods.
- * {@code HandlerExceptionResolver} beans for invoking {@code @ExceptionHandler}
- * controller methods and for mapping Spring exception to HTTP status codes.
- *
- *
- * The {@code HandlerAdapter} is further configured with the following, which apply
- * globally (across controllers invoked though the {@code AnnotationMethodHandlerAdapter}):
- *
- *
- * {@link ConversionService} - a custom instance can be provided via
- * {@link #conversionService(ConversionService)}. Otherwise it defaults to a fresh
- * {@link ConversionService} instance created by the default
- * {@link FormattingConversionServiceFactoryBean}.
- * {@link Validator} - a custom instance can be provided via
- * {@link #validator(Validator)}. Otherwise it defaults to a fresh {@code Validator}
- * instance created by the default {@link LocalValidatorFactoryBean} assuming
- * JSR-303 API is present on the classpath .
- * {@code HttpMessageConverter} beans including the {@link
- * Jaxb2RootElementHttpMessageConverter} assuming JAXB2 is present on the
- * classpath , the {@link MappingJacksonHttpMessageConverter} assuming Jackson
- * is present on the classpath , and the {@link AtomFeedHttpMessageConverter} and the
- * {@link RssChannelHttpMessageConverter} converters assuming Rome is present on
- * the classpath .
- * Optionally, custom {@code WebArgumentResolver} beans to use for resolving
- * custom arguments to handler methods. These are typically implemented to detect
- * special parameter types, resolving well-known argument values for them.
- *
- *
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public final class MvcAnnotationDriven extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = MvcAnnotationDrivenExecutor.class;
-
- private Object conversionService;
-
- private Object validator;
-
- private Object messageCodesResolver;
-
- private boolean shouldRegisterDefaultMessageConverters = true;
-
- private ManagedList super Object> messageConverters = new ManagedList();
-
- private ManagedList super Object> argumentResolvers = new ManagedList();
-
- /**
- * Creates an MvcAnnotationDriven specification.
- */
- public MvcAnnotationDriven() {
- super(EXECUTOR_TYPE);
- }
-
- /**
- * The ConversionService bean instance to use for type conversion during
- * field binding. This is not required input. It only needs to be provided
- * explicitly if custom converters or formatters need to be configured.
- *
- *
If not provided, a default FormattingConversionService is registered
- * that contains converters to/from standard JDK types. In addition, full
- * support for date/time formatting will be installed if the Joda Time
- * library is present on the classpath.
- *
- * @param conversionService the ConversionService instance to use
- */
- public MvcAnnotationDriven conversionService(ConversionService conversionService) {
- this.conversionService = conversionService;
- return this;
- }
-
- /**
- *
The ConversionService to use for type conversion during field binding.
- * This is an alternative to {@link #conversionService(ConversionService)}
- * allowing you to provide a bean name rather than a bean instance.
- *
- * @param conversionService the ConversionService bean name
- */
- public MvcAnnotationDriven conversionService(String conversionService) {
- this.conversionService = conversionService;
- return this;
- }
-
- Object conversionService() {
- return this.conversionService;
- }
-
- /**
- * The HttpMessageConverter types to use for converting @RequestBody method
- * parameters and @ResponseBody method return values. HttpMessageConverter
- * registrations provided here will take precedence over HttpMessageConverter
- * types registered by default.
- * Also see {@link #shouldRegisterDefaultMessageConverters(boolean)} if
- * default registrations are to be turned off altogether.
- *
- * @param converters the message converters
- */
- public MvcAnnotationDriven messageConverters(HttpMessageConverter>... converters) {
- for (HttpMessageConverter> converter : converters) {
- this.messageConverters.add(converter);
- }
- return this;
- }
-
- void messageConverters(ManagedList converterBeanDefinitions) {
- this.messageConverters.addAll(converterBeanDefinitions);
- }
-
- ManagedList> messageConverters() {
- return this.messageConverters;
- }
-
- /**
- * Indicates whether or not default HttpMessageConverter registrations should
- * be added in addition to the ones provided via
- * {@link #messageConverters(HttpMessageConverter...)}
- *
- * @param shouldRegister true will result in registration of defaults.
- */
- public MvcAnnotationDriven shouldRegisterDefaultMessageConverters(boolean shouldRegister) {
- this.shouldRegisterDefaultMessageConverters = shouldRegister;
- return this;
- }
-
- boolean shouldRegisterDefaultMessageConverters() {
- return this.shouldRegisterDefaultMessageConverters;
- }
-
- public MvcAnnotationDriven argumentResolvers(HandlerMethodArgumentResolver... resolvers) {
- for (HandlerMethodArgumentResolver resolver : resolvers) {
- this.argumentResolvers.add(resolver);
- }
- return this;
- }
-
- public MvcAnnotationDriven argumentResolvers(WebArgumentResolver... resolvers) {
- for (WebArgumentResolver resolver : resolvers) {
- this.argumentResolvers.add(new ServletWebArgumentResolverAdapter(resolver));
- }
- return this;
- }
-
- void argumentResolvers(ManagedList resolverBeanDefinitions) {
- this.argumentResolvers.addAll(resolverBeanDefinitions);
- }
-
- ManagedList> argumentResolvers() {
- return this.argumentResolvers;
- }
-
- /**
- * The Validator bean instance to use to validate Controller model objects.
- * This is not required input. It only needs to be specified explicitly if
- * a custom Validator needs to be configured.
- *
- * If not specified, JSR-303 validation will be installed if a JSR-303
- * provider is present on the classpath.
- *
- * @param validator the Validator bean instance
- */
- public MvcAnnotationDriven validator(Validator validator) {
- this.validator = validator;
- return this;
- }
-
- /**
- * The Validator bean instance to use to validate Controller model objects.
- * This is an alternative to {@link #validator(Validator)} allowing you to
- * provide a bean name rather than a bean instance.
- *
- * @param validator the Validator bean name
- */
- public MvcAnnotationDriven validator(String validator) {
- this.validator = validator;
- return this;
- }
-
- Object validator() {
- return this.validator;
- }
-
- /**
- * The MessageCodesResolver to use to build message codes from data binding
- * and validation error codes. This is not required input. If not specified
- * the DefaultMessageCodesResolver is used.
- *
- * @param messageCodesResolver the MessageCodesResolver bean instance
- */
- public MvcAnnotationDriven messageCodesResolver(MessageCodesResolver messageCodesResolver) {
- this.messageCodesResolver = messageCodesResolver;
- return this;
- }
-
- /**
- * The MessageCodesResolver to use to build message codes from data binding
- * and validation error codes. This is an alternative to
- * {@link #messageCodesResolver(MessageCodesResolver)} allowing you to provide
- * a bean name rather than a bean instance.
- *
- * @param messageCodesResolver the MessageCodesResolver bean name
- */
- public MvcAnnotationDriven messageCodesResolver(String messageCodesResolver) {
- this.messageCodesResolver = messageCodesResolver;
- return this;
- }
-
- Object messageCodesResolver() {
- return this.messageCodesResolver;
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDrivenExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDrivenExecutor.java
deleted file mode 100644
index 1337ec4660f..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDrivenExecutor.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.format.support.FormattingConversionServiceFactoryBean;
-import org.springframework.http.converter.ByteArrayHttpMessageConverter;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.ResourceHttpMessageConverter;
-import org.springframework.http.converter.StringHttpMessageConverter;
-import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
-import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
-import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
-import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
-import org.springframework.http.converter.xml.SourceHttpMessageConverter;
-import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
-import org.springframework.util.ClassUtils;
-import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
-import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
-import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
-import org.springframework.web.servlet.handler.MappedInterceptor;
-import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
-import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
-import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
-
-/**
- * Executes {@link MvcAnnotationDriven} specifications, creating and registering
- * bean definitions as appropriate based on the configuration within.
- *
- * @author Keith Donald
- * @author Juergen Hoeller
- * @author Arjen Poutsma
- * @author Rossen Stoyanchev
- * @since 3.1
- * @see MvcAnnotationDriven
- */
-final class MvcAnnotationDrivenExecutor extends AbstractSpecificationExecutor {
-
- private static final boolean jsr303Present = ClassUtils.isPresent("javax.validation.Validator",
- AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
-
- private static final boolean jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder",
- AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
-
- private static final boolean jacksonPresent = ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper",
- AnnotationDrivenBeanDefinitionParser.class.getClassLoader())
- && ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator",
- AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
-
- private static boolean romePresent = ClassUtils.isPresent("com.sun.syndication.feed.WireFeed",
- AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
-
- @Override
- public void doExecute(MvcAnnotationDriven spec, SpecificationContext specContext) {
- ComponentRegistrar registrar = specContext.getRegistrar();
- Object source = spec.source();
-
- RootBeanDefinition methodMappingDef = new RootBeanDefinition(RequestMappingHandlerMethodMapping.class);
- methodMappingDef.setSource(source);
- methodMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- methodMappingDef.getPropertyValues().add("order", 0);
- String methodMappingName = registrar.registerWithGeneratedName(methodMappingDef);
-
- Object conversionService = getConversionService(spec, registrar);
- Object validator = getValidator(spec, registrar);
- Object messageCodesResolver = getMessageCodesResolver(spec, registrar);
-
- RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
- bindingDef.setSource(source);
- bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- bindingDef.getPropertyValues().add("conversionService", conversionService);
- bindingDef.getPropertyValues().add("validator", validator);
- bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);
-
- ManagedList super Object> messageConverters = getMessageConverters(spec, registrar);
-
- RootBeanDefinition methodAdapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class);
- methodAdapterDef.setSource(source);
- methodAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- methodAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
- methodAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
- if (!spec.argumentResolvers().isEmpty()) {
- methodAdapterDef.getPropertyValues().add("customArgumentResolvers", spec.argumentResolvers());
- }
- String methodAdapterName = registrar.registerWithGeneratedName(methodAdapterDef);
-
- RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
- csInterceptorDef.setSource(source);
- csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
- RootBeanDefinition mappedCsInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
- mappedCsInterceptorDef.setSource(source);
- mappedCsInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
- mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
- String mappedInterceptorName = registrar.registerWithGeneratedName(mappedCsInterceptorDef);
-
- RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(
- ExceptionHandlerExceptionResolver.class);
- methodExceptionResolver.setSource(source);
- methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
- methodExceptionResolver.getPropertyValues().add("order", 0);
- String methodExceptionResolverName = registrar.registerWithGeneratedName(methodExceptionResolver);
-
- RootBeanDefinition responseStatusExceptionResolver = new RootBeanDefinition(
- ResponseStatusExceptionResolver.class);
- responseStatusExceptionResolver.setSource(source);
- responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- responseStatusExceptionResolver.getPropertyValues().add("order", 1);
- String responseStatusExceptionResolverName = registrar
- .registerWithGeneratedName(responseStatusExceptionResolver);
-
- RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
- defaultExceptionResolver.setSource(source);
- defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- defaultExceptionResolver.getPropertyValues().add("order", 2);
- String defaultExceptionResolverName = registrar.registerWithGeneratedName(defaultExceptionResolver);
-
- CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(spec.sourceName(), source);
- compDefinition.addNestedComponent(new BeanComponentDefinition(methodMappingDef, methodMappingName));
- compDefinition.addNestedComponent(new BeanComponentDefinition(methodAdapterDef, methodAdapterName));
- compDefinition.addNestedComponent(new BeanComponentDefinition(methodExceptionResolver, methodExceptionResolverName));
- compDefinition.addNestedComponent(new BeanComponentDefinition(responseStatusExceptionResolver,
- responseStatusExceptionResolverName));
- compDefinition.addNestedComponent(new BeanComponentDefinition(defaultExceptionResolver,
- defaultExceptionResolverName));
- compDefinition.addNestedComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));
- registrar.registerComponent(compDefinition);
- }
-
- private Object getConversionService(MvcAnnotationDriven spec, ComponentRegistrar registrar) {
- if (spec.conversionService() != null) {
- return getBeanOrReference(spec.conversionService());
- } else {
- RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);
- conversionDef.setSource(spec.source());
- conversionDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- String conversionName = registrar.registerWithGeneratedName(conversionDef);
- registrar.registerComponent(new BeanComponentDefinition(conversionDef, conversionName));
- return new RuntimeBeanReference(conversionName);
- }
- }
-
- private Object getValidator(MvcAnnotationDriven spec, ComponentRegistrar registrar) {
- if (spec.validator() != null) {
- return getBeanOrReference(spec.validator());
- } else if (jsr303Present) {
- RootBeanDefinition validatorDef = new RootBeanDefinition(LocalValidatorFactoryBean.class);
- validatorDef.setSource(spec.source());
- validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- String validatorName = registrar.registerWithGeneratedName(validatorDef);
- registrar.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
- return new RuntimeBeanReference(validatorName);
- } else {
- return null;
- }
- }
-
- private Object getMessageCodesResolver(MvcAnnotationDriven spec, ComponentRegistrar registrar) {
- if (spec.messageCodesResolver() != null) {
- return getBeanOrReference(spec.messageCodesResolver());
- } else {
- return null;
- }
- }
-
- private ManagedList super Object> getMessageConverters(MvcAnnotationDriven spec, ComponentRegistrar registrar) {
- ManagedList super Object> messageConverters = new ManagedList();
- Object source = spec.source();
- messageConverters.setSource(source);
- messageConverters.addAll(spec.messageConverters());
- if (spec.shouldRegisterDefaultMessageConverters()) {
- messageConverters.add(createConverterBeanDefinition(ByteArrayHttpMessageConverter.class, source));
- RootBeanDefinition stringConverterDef = createConverterBeanDefinition(StringHttpMessageConverter.class,
- source);
- stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
- messageConverters.add(stringConverterDef);
- messageConverters.add(createConverterBeanDefinition(ResourceHttpMessageConverter.class, source));
- messageConverters.add(createConverterBeanDefinition(SourceHttpMessageConverter.class, source));
- messageConverters.add(createConverterBeanDefinition(XmlAwareFormHttpMessageConverter.class, source));
- if (jaxb2Present) {
- messageConverters
- .add(createConverterBeanDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
- }
- if (jacksonPresent) {
- messageConverters.add(createConverterBeanDefinition(MappingJacksonHttpMessageConverter.class, source));
- }
- if (romePresent) {
- messageConverters.add(createConverterBeanDefinition(AtomFeedHttpMessageConverter.class, source));
- messageConverters.add(createConverterBeanDefinition(RssChannelHttpMessageConverter.class, source));
- }
- }
- return messageConverters;
- }
-
- @SuppressWarnings("rawtypes")
- private RootBeanDefinition createConverterBeanDefinition(Class extends HttpMessageConverter> converterClass,
- Object source) {
- RootBeanDefinition beanDefinition = new RootBeanDefinition(converterClass);
- beanDefinition.setSource(source);
- beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- return beanDefinition;
- }
-
- private Object getBeanOrReference(Object bean) {
- if (bean != null && bean instanceof String) {
- return new RuntimeBeanReference((String) bean);
- } else {
- return bean;
- }
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandler.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandler.java
deleted file mode 100644
index fcccac2f04f..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
-
-/**
- * Specifies the Spring MVC "default-servlet-handler" container feature. The
- * feature provides the following fine-grained configuration:
- *
- *
- * {@link DefaultServletHttpRequestHandler} for serving static files by
- * forwarding to the Servlet container's "default" Servlet.
- * {@link SimpleUrlHandlerMapping} to map the above request handler to "/**"
- * {@link HttpRequestHandlerAdapter} to enable the DispatcherServlet to be
- * able to invoke the above request handler.
- *
- *
- * This handler will forward all requests to the default Servlet. Therefore
- * it is important that it remains last in the order of all other URL
- * HandlerMappings. That will be the case if you use the {@link MvcAnnotationDriven}
- * feature or alternatively if you are setting up your customized HandlerMapping
- * instance be sure to set its "order" property to a value lower than that of
- * the DefaultServletHttpRequestHandler, which is Integer.MAX_VALUE.
- *
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public final class MvcDefaultServletHandler extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = MvcDefaultServletHandlerExecutor.class;
-
- private String defaultServletName;
-
- /**
- * Creates an instance of MvcDefaultServletHandler without.
- * If this constructor is used the {@link DefaultServletHttpRequestHandler}
- * will try to auto-detect the container's default Servlet at startup time
- * using a list of known names.
- *
- *
If the default Servlet cannot be detected because of using an
- * unknown container or because it has been manually configured, an
- * alternate constructor provided here can be used to specify the
- * servlet name explicitly.
- */
- public MvcDefaultServletHandler() {
- super(EXECUTOR_TYPE);
- }
-
- /**
- * The name of the default Servlet to forward to for static resource requests.
- * The {@link DefaultServletHttpRequestHandler} will try to auto-detect the
- * container's default Servlet at startup time using a list of known names.
- * However if the default Servlet cannot be detected because of using an unknown
- * container or because it has been manually configured, you can use this
- * constructor to set the servlet name explicitly.
- *
- * @param defaultServletName the name of the default servlet
- */
- public MvcDefaultServletHandler(String defaultServletName) {
- this();
- this.defaultServletName = defaultServletName;
- }
-
- String defaultServletName() {
- return this.defaultServletName;
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java
deleted file mode 100644
index aa57d5abb49..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.web.servlet.config;
-
-import java.util.Map;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.util.StringUtils;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
-
-/**
- * Executes {@link MvcDefaultServletHandler} specifications, creating and
- * registering bean definitions as appropriate based on the configuration
- * within.
- *
- * @author Jeremy Grelle
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-final class MvcDefaultServletHandlerExecutor extends AbstractSpecificationExecutor {
-
- private static final String HANDLER_ADAPTER_BEAN_NAME = "org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter";
-
- @Override
- protected void doExecute(MvcDefaultServletHandler spec, SpecificationContext specContext) {
- BeanDefinitionRegistry registry = specContext.getRegistry();
- ComponentRegistrar registrar = specContext.getRegistrar();
- Object source = spec.source();
-
- if (!registry.containsBeanDefinition(HANDLER_ADAPTER_BEAN_NAME)) {
- RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
- handlerAdapterDef.setSource(source);
- handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
- registrar.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
- }
-
- RootBeanDefinition defaultServletHandlerDef = new RootBeanDefinition(DefaultServletHttpRequestHandler.class);
- defaultServletHandlerDef.setSource(source);
- defaultServletHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- if (StringUtils.hasText(spec.defaultServletName())) {
- defaultServletHandlerDef.getPropertyValues().add("defaultServletName", spec.defaultServletName());
- }
- String defaultServletHandlerName = registrar.registerWithGeneratedName(defaultServletHandlerDef);
- registry.registerBeanDefinition(defaultServletHandlerName, defaultServletHandlerDef);
- registrar.registerComponent(new BeanComponentDefinition(defaultServletHandlerDef, defaultServletHandlerName));
-
- Map urlMap = new ManagedMap();
- urlMap.put("/**", defaultServletHandlerName);
- RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
- handlerMappingDef.setSource(source);
- handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
- String handlerMappingBeanName = registrar.registerWithGeneratedName(handlerMappingDef);
- registry.registerBeanDefinition(handlerMappingBeanName, handlerMappingDef);
- registrar.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingBeanName));
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptors.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptors.java
deleted file mode 100644
index 8169fdcfd08..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptors.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.util.StringUtils;
-import org.springframework.web.context.request.WebRequestInterceptor;
-import org.springframework.web.servlet.HandlerInterceptor;
-import org.springframework.web.servlet.handler.MappedInterceptor;
-
-/**
- * Specifies the Spring MVC "interceptors" container feature. The feature
- * registers one or more {@link MappedInterceptor} bean definitions. A
- * MappedInterceptor encapsulates an interceptor and one or more (optional)
- * path patterns to which the interceptor is mapped. The interceptor can be
- * of type {@link HandlerInterceptor} or {@link WebRequestInterceptor}.
- * An interceptor can also be provided without path patterns in which case
- * it applies globally to all handler invocations.
- *
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public class MvcInterceptors extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = MvcInterceptorsExecutor.class;
-
- private Map interceptorMappings = new LinkedHashMap();
-
- /**
- * Creates an MvcInterceptors instance.
- */
- public MvcInterceptors() {
- super(EXECUTOR_TYPE);
- }
-
- /**
- * Add one or more {@link HandlerInterceptor HandlerInterceptors} that should
- * intercept all handler invocations.
- *
- * @param interceptors one or more interceptors
- */
- public MvcInterceptors globalInterceptors(HandlerInterceptor... interceptors) {
- addInterceptorMappings(null, interceptors);
- return this;
- }
-
- /**
- * Add one or more {@link WebRequestInterceptor WebRequestInterceptors} that should
- * intercept all handler invocations.
- *
- * @param interceptors one or more interceptors
- */
- public MvcInterceptors globalInterceptors(WebRequestInterceptor... interceptors) {
- addInterceptorMappings(null, interceptors);
- return this;
- }
-
- /**
- * Add one or more interceptors by bean name that should intercept all handler
- * invocations.
- *
- * @param interceptors interceptor bean names
- */
- public MvcInterceptors globalInterceptors(String... interceptors) {
- addInterceptorMappings(null, interceptors);
- return this;
- }
-
- /**
- * Add one or more {@link HandlerInterceptor HandlerInterceptors} and map
- * them to the specified path patterns.
- *
- * @param pathPatterns the pathPatterns to map the interceptor to
- * @param interceptors the interceptors
- */
- public MvcInterceptors mappedInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors) {
- addInterceptorMappings(pathPatterns, interceptors);
- return this;
- }
-
- /**
- * Add one or more {@link WebRequestInterceptor WebRequestInterceptors} and
- * map them to the specified path patterns.
- *
- * @param pathPatterns the pathPatterns to map the interceptor to
- * @param interceptors the interceptors
- */
- public MvcInterceptors mappedInterceptors(String[] pathPatterns, WebRequestInterceptor... interceptors) {
- addInterceptorMappings(pathPatterns, interceptors);
- return this;
- }
-
- /**
- * Add one or more interceptors by bean name and map them to the specified
- * path patterns.
- *
- * @param pathPatterns the pathPatterns to map to
- * @param interceptors the interceptors
- */
- public MvcInterceptors mappedInterceptors(String[] pathPatterns, String... interceptors) {
- addInterceptorMappings(pathPatterns, interceptors);
- return this;
- }
-
- void interceptor(String[] pathPatterns, BeanDefinitionHolder interceptor) {
- addInterceptorMappings(pathPatterns, new Object[] { interceptor });
- }
-
- Map interceptorMappings() {
- return Collections.unmodifiableMap(interceptorMappings);
- }
-
- private void addInterceptorMappings(String[] pathPatterns, Object[] interceptors) {
- for (Object interceptor : interceptors) {
- interceptorMappings.put(interceptor, pathPatterns);
- }
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- if (interceptorMappings.size() == 0) {
- problems.error("No interceptors defined.");
- }
- for (Object interceptor : interceptorMappings.keySet()) {
- if (interceptor == null) {
- problems.error("Null interceptor provided.");
- }
- if (interceptorMappings.get(interceptor) != null) {
- for (String pattern : interceptorMappings.get(interceptor)) {
- if (!StringUtils.hasText(pattern)) {
- problems.error("Empty path pattern specified for " + interceptor);
- }
- }
- }
- }
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptorsExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptorsExecutor.java
deleted file mode 100644
index 029caaf24f7..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptorsExecutor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.web.servlet.handler.MappedInterceptor;
-
-/**
- * Executes {@link MvcInterceptors} specification, creating and registering
- * bean definitions as appropriate based on the configuration within.
- *
- * @author Keith Donald
- * @author Rossen Stoyanchev
- *
- * @since 3.1
- */
-final class MvcInterceptorsExecutor extends AbstractSpecificationExecutor {
-
- @Override
- protected void doExecute(MvcInterceptors spec, SpecificationContext specContext) {
- ComponentRegistrar registrar = specContext.getRegistrar();
- Object source = spec.source();
-
- CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(spec.sourceName(), source);
-
- for (Object interceptor : spec.interceptorMappings().keySet()) {
- RootBeanDefinition beanDef = new RootBeanDefinition(MappedInterceptor.class);
- beanDef.setSource(source);
- beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- beanDef.getConstructorArgumentValues().addIndexedArgumentValue(0,
- spec.interceptorMappings().get(interceptor));
- beanDef.getConstructorArgumentValues().addIndexedArgumentValue(1, interceptor);
-
- String beanName = registrar.registerWithGeneratedName(beanDef);
- compDefinition.addNestedComponent(new BeanComponentDefinition(beanDef, beanName));
- }
-
- registrar.registerComponent(compDefinition);
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResources.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResources.java
deleted file mode 100644
index e85d12dbac1..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResources.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.web.servlet.config;
-
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.core.Ordered;
-import org.springframework.core.io.Resource;
-import org.springframework.util.StringUtils;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
-import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
-
-/**
- * Specifies the Spring MVC "resources" container feature. The
- * feature provides the following fine-grained configuration:
- *
- *
- * {@link ResourceHttpRequestHandler} to serve static resources from a
- * list of web-root relative, classpath, or other locations.
- * {@link SimpleUrlHandlerMapping} to map the above request handler to a
- * a specific path pattern (e.g. "/resources/**").
- * {@link HttpRequestHandlerAdapter} to enable the DispatcherServlet to be
- * able to invoke the above request handler.
- *
- *
- * @author Rossen Stoynchev
- * @since 3.1
- */
-public final class MvcResources extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = MvcResourcesExecutor.class;
-
- private Object[] locations;
-
- private String mapping;
-
- private Object cachePeriod;
-
- private Object order = Ordered.LOWEST_PRECEDENCE - 1;
-
- /**
- * Create an MvcResources specification instance. See alternate constructor
- * you prefer to use {@link Resource} instances instead of {@code String}-based
- * resource locations.
- *
- * @param mapping - the URL path pattern within the current Servlet context to
- * use to identify resource requests (e.g. "/resources/**").
- * @param locations - locations of resources containing static content to be
- * served. Each location must point to a valid directory. Locations will be
- * checked in the order specified. For example if "/" and
- * "classpath:/META-INF/public-web-resources/" are configured resources will
- * be served from the Web root and from any JAR on the classpath that contains
- * a /META-INF/public-web-resources/ directory, with resources under the Web root
- * taking precedence.
- */
- public MvcResources(String mapping, String... locations) {
- super(EXECUTOR_TYPE);
- this.locations = locations;
- this.mapping = mapping;
- }
-
- /**
- * Create an MvcResources specification instance. See alternate constructor
- * defined here if you prefer to use String-based path patterns.
- *
- * @param mapping - the URL path pattern within the current Servlet context to
- * use to identify resource requests (e.g. "/resources/**").
- * @param resources - Spring {@link Resource} objects containing static
- * content to be served. Resources will be checked in the order specified.
- */
- public MvcResources(String mapping, Resource... resources) {
- super(EXECUTOR_TYPE);
- this.locations = resources;
- this.mapping = mapping;
- }
-
- /**
- * The period of time resources should be cached for in seconds.
- * The default is to not send any cache headers but rather to rely on
- * last-modified timestamps only.
- * Set this to 0 in order to send cache headers that prevent caching,
- * or to a positive number of seconds in order to send cache headers
- * with the given max-age value.
- *
- * @param cachePeriod the cache period in seconds
- */
- public MvcResources cachePeriod(Integer cachePeriod) {
- this.cachePeriod = cachePeriod;
- return this;
- }
-
- /**
- * Specify a cachePeriod as a String. An alternative to {@link #cachePeriod(Integer)}.
- * The String must represent an Integer after placeholder and SpEL expression
- * resolution.
- *
- * @param cachePeriod the cache period in seconds
- */
- public MvcResources cachePeriod(String cachePeriod) {
- this.cachePeriod = cachePeriod;
- return this;
- }
-
- /**
- * Specify a cachePeriod as a String. An alternative to {@link #cachePeriod(Integer)}.
- * The String must represent an Integer after placeholder and SpEL expression
- * resolution.
- *
Sets the order for the SimpleUrlHandlerMapping used to match resource
- * requests relative to order value for other HandlerMapping instances
- * such as the {@link DefaultAnnotationHandlerMapping} used to match
- * controller requests.
- *
- * @param order the order to use. The default value is
- * {@link Ordered#LOWEST_PRECEDENCE} - 1.
- */
- public MvcResources order(Integer order) {
- this.order = order;
- return this;
- }
-
- /**
- * Specify an order as a String. An alternative to {@link #order(Integer)}.
- * The String must represent an Integer after placeholder and SpEL expression
- * resolution.
- *
- * @param order the order to use. The default value is
- * {@link Ordered#LOWEST_PRECEDENCE} - 1.
- */
- public MvcResources order(String order) {
- this.order = order;
- return this;
- }
-
- // Package private accessors
-
- Object cachePeriod() {
- return cachePeriod;
- }
-
- Object[] locations() {
- return this.locations;
- }
-
- String mapping() {
- return mapping;
- }
-
- Object order() {
- return order;
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- if (!StringUtils.hasText(mapping)) {
- problems.error("Mapping is required");
- }
- if (locations == null || locations.length == 0) {
- problems.error("At least one location is required");
- }
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResourcesExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResourcesExecutor.java
deleted file mode 100644
index a61db228745..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcResourcesExecutor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.web.servlet.config;
-
-import java.util.Map;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
-
-/**
- * Executes {@link MvcResources} specifications, creating and registering
- * bean definitions as appropriate based on the configuration within.
- *
- * @author Keith Donald
- * @author Jeremy Grelle
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-final class MvcResourcesExecutor extends AbstractSpecificationExecutor {
-
- private static final String HANDLER_ADAPTER_BEAN_NAME = "org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter";
-
- @Override
- protected void doExecute(MvcResources spec, SpecificationContext specContext) {
- BeanDefinitionRegistry registry = specContext.getRegistry();
- ComponentRegistrar registrar = specContext.getRegistrar();
- Object source = spec.source();
-
- if (!registry.containsBeanDefinition(HANDLER_ADAPTER_BEAN_NAME)) {
- RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
- handlerAdapterDef.setSource(source);
- handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
- registrar.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
- }
-
- RootBeanDefinition resourceHandlerDef = new RootBeanDefinition(ResourceHttpRequestHandler.class);
- resourceHandlerDef.setSource(source);
- resourceHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- resourceHandlerDef.getPropertyValues().add("locations", spec.locations());
- if (spec.cachePeriod() != null) {
- resourceHandlerDef.getPropertyValues().add("cacheSeconds", spec.cachePeriod());
- }
- String resourceHandlerBeanName = registrar.registerWithGeneratedName(resourceHandlerDef);
- registry.registerBeanDefinition(resourceHandlerBeanName, resourceHandlerDef);
- registrar.registerComponent(new BeanComponentDefinition(resourceHandlerDef, resourceHandlerBeanName));
-
- Map urlMap = new ManagedMap();
- urlMap.put(spec.mapping(), resourceHandlerBeanName);
- RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
- handlerMappingDef.setSource(source);
- handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
- if (spec.order() != null) {
- handlerMappingDef.getPropertyValues().add("order", spec.order());
- }
- String beanName = registrar.registerWithGeneratedName(handlerMappingDef);
- registry.registerBeanDefinition(beanName, handlerMappingDef);
- registrar.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName));
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllers.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllers.java
deleted file mode 100644
index 6b13652e411..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllers.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.beans.factory.parsing.ProblemCollector;
-import org.springframework.context.config.AbstractFeatureSpecification;
-import org.springframework.context.config.FeatureSpecificationExecutor;
-import org.springframework.util.StringUtils;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
-
-/**
- * Specifies the Spring MVC "View Controllers" container feature. The
- * feature allows specifying one or more path to view name mappings.
- * It sets up the following fine-grained configuration:
- *
- *
- * {@link ParameterizableViewController} for each path/view name pair.
- * {@link SimpleUrlHandlerMapping} mapping each view controller to its path.
- * {@link SimpleControllerHandlerAdapter} to enable the DispatcherServlet
- * to invoke the view controllers.
- *
- *
- * @author Rossen Stoyanchev
- * @author Chris Beams
- * @since 3.1
- */
-public final class MvcViewControllers extends AbstractFeatureSpecification {
-
- private static final Class extends FeatureSpecificationExecutor> EXECUTOR_TYPE = MvcViewControllersExecutor.class;
-
- private Map mappings = new HashMap();
-
- public MvcViewControllers(String path) {
- this(path, null);
- }
-
- public MvcViewControllers(String path, String viewName) {
- super(EXECUTOR_TYPE);
- this.mappings.put(path, viewName);
- }
-
- public MvcViewControllers viewController(String path) {
- return this.viewController(path, null);
- }
-
- public MvcViewControllers viewController(String path, String viewName) {
- this.mappings.put(path, viewName);
- return this;
- }
-
- Map mappings() {
- return Collections.unmodifiableMap(mappings);
- }
-
- @Override
- protected void doValidate(ProblemCollector problems) {
- if (mappings.size() == 0) {
- problems.error("At least one ViewController must be defined");
- }
- for (String path : mappings.keySet()) {
- if (!StringUtils.hasText(path)) {
- problems.error("The path attribute in a ViewController is required");
- }
- String viewName = mappings.get(path);
- if (viewName != null && viewName.isEmpty()) {
- problems.error("The view name in a ViewController may be null but not empty.");
- }
- }
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllersExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllersExecutor.java
deleted file mode 100644
index 33e82089ce0..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcViewControllersExecutor.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */package org.springframework.web.servlet.config;
-
-import java.util.Map;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.config.AbstractSpecificationExecutor;
-import org.springframework.context.config.SpecificationContext;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
-
-/**
- * Executes {@link MvcViewControllers} specification, creating and registering
- * bean definitions as appropriate based on the configuration within.
- *
- * @author Keith Donald
- * @author Christian Dupuis
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-final class MvcViewControllersExecutor extends AbstractSpecificationExecutor {
-
- private static final String HANDLER_ADAPTER_BEAN_NAME = "org.springframework.web.servlet.config.viewControllerHandlerAdapter";
-
- private static final String HANDLER_MAPPING_BEAN_NAME = "org.springframework.web.servlet.config.viewControllerHandlerMapping";
-
- @Override
- protected void doExecute(MvcViewControllers spec, SpecificationContext specContext) {
- BeanDefinitionRegistry registry = specContext.getRegistry();
- ComponentRegistrar registrar = specContext.getRegistrar();
- Object source = spec.source();
-
- if (!registry.containsBeanDefinition(HANDLER_ADAPTER_BEAN_NAME)) {
- RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(SimpleControllerHandlerAdapter.class);
- handlerAdapterDef.setSource(source);
- handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
- registrar.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
- }
-
- BeanDefinition handlerMappingBeanDef = null;
- if (!registry.containsBeanDefinition(HANDLER_MAPPING_BEAN_NAME)) {
- RootBeanDefinition beanDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
- beanDef.setSource(source);
- beanDef.getPropertyValues().add("order", "1");
- beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- registry.registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, beanDef);
- registrar.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_BEAN_NAME));
- handlerMappingBeanDef = beanDef;
- } else {
- handlerMappingBeanDef = registry.getBeanDefinition(HANDLER_MAPPING_BEAN_NAME);
- }
-
- for (Map.Entry entry : spec.mappings().entrySet()) {
- RootBeanDefinition viewControllerDef = new RootBeanDefinition(ParameterizableViewController.class);
- viewControllerDef.setSource(source);
- if (entry.getValue() != null) {
- viewControllerDef.getPropertyValues().add("viewName", entry.getValue());
- }
- if (!handlerMappingBeanDef.getPropertyValues().contains("urlMap")) {
- handlerMappingBeanDef.getPropertyValues().add("urlMap", new ManagedMap());
- }
- @SuppressWarnings("unchecked")
- Map urlMap = (Map) handlerMappingBeanDef
- .getPropertyValues().getPropertyValue("urlMap").getValue();
- urlMap.put(entry.getKey(), viewControllerDef);
- }
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java
index 058652afcf2..03654ab9e5b 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 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,40 +16,89 @@
package org.springframework.web.servlet.config;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.util.StringUtils;
+import java.util.Map;
+
import org.w3c.dom.Element;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.core.Ordered;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
+import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
+import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
+
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a
- * {@code resources} element.
+ * {@code resources} element to register a {@link ResourceHttpRequestHandler}.
+ * Will also register a {@link SimpleUrlHandlerMapping} for mapping resource requests,
+ * and a {@link HttpRequestHandlerAdapter} if necessary.
*
- * @author Rossen Stoyanchev
+ * @author Keith Donald
+ * @author Jeremy Grelle
* @since 3.0.4
- * @see MvcResources
- * @see MvcResourcesExecutor
*/
-class ResourcesBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+class ResourcesBeanDefinitionParser extends AbstractHttpRequestHandlerBeanDefinitionParser implements BeanDefinitionParser {
- /**
- * Parses the {@code } tag
- */
- public FeatureSpecification doParse(Element element, ParserContext parserContext) {
- String mapping = element.getAttribute("mapping");
- String[] locations =
- StringUtils.commaDelimitedListToStringArray(element.getAttribute("location"));
-
- MvcResources spec = new MvcResources(mapping, locations);
- if (element.hasAttribute("cache-period")) {
- spec.cachePeriod(element.getAttribute("cache-period"));
+ @Override
+ public void doParse(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+ registerResourceMappings(parserContext, element, source);
+ }
+
+ private void registerResourceMappings(ParserContext parserContext, Element element, Object source) {
+ String resourceHandlerName = registerResourceHandler(parserContext, element, source);
+ if (resourceHandlerName == null) {
+ return;
}
- if (element.hasAttribute("order")) {
- spec.order(element.getAttribute("order"));
+
+ Map urlMap = new ManagedMap();
+ String resourceRequestPath = element.getAttribute("mapping");
+ if (!StringUtils.hasText(resourceRequestPath)) {
+ parserContext.getReaderContext().error("The 'mapping' attribute is required.", parserContext.extractSource(element));
+ return;
+ }
+ urlMap.put(resourceRequestPath, resourceHandlerName);
+
+ RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
+ handlerMappingDef.setSource(source);
+ handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
+
+ String order = element.getAttribute("order");
+ // use a default of near-lowest precedence, still allowing for even lower precedence in other mappings
+ handlerMappingDef.getPropertyValues().add("order", StringUtils.hasText(order) ? order : Ordered.LOWEST_PRECEDENCE - 1);
+
+ String beanName = parserContext.getReaderContext().generateBeanName(handlerMappingDef);
+ parserContext.getRegistry().registerBeanDefinition(beanName, handlerMappingDef);
+ parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName));
+ }
+
+ private String registerResourceHandler(ParserContext parserContext, Element element, Object source) {
+ String locationAttr = element.getAttribute("location");
+ if (!StringUtils.hasText(locationAttr)) {
+ parserContext.getReaderContext().error("The 'location' attribute is required.", parserContext.extractSource(element));
+ return null;
+ }
+
+ RootBeanDefinition resourceHandlerDef = new RootBeanDefinition(ResourceHttpRequestHandler.class);
+ resourceHandlerDef.setSource(source);
+ resourceHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ resourceHandlerDef.getPropertyValues().add("locations", StringUtils.commaDelimitedListToStringArray(locationAttr));
+
+ String cacheSeconds = element.getAttribute("cache-period");
+ if (StringUtils.hasText(cacheSeconds)) {
+ resourceHandlerDef.getPropertyValues().add("cacheSeconds", cacheSeconds);
}
- return spec;
+ String beanName = parserContext.getReaderContext().generateBeanName(resourceHandlerDef);
+ parserContext.getRegistry().registerBeanDefinition(beanName, resourceHandlerDef);
+ parserContext.registerComponent(new BeanComponentDefinition(resourceHandlerDef, beanName));
+ return beanName;
}
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java
index 5c6f3293be7..36b985e99c3 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java
@@ -16,30 +16,88 @@
package org.springframework.web.servlet.config;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
-import org.springframework.context.config.FeatureSpecification;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
+import java.util.Map;
+
import org.w3c.dom.Element;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
+import org.springframework.web.servlet.mvc.ParameterizableViewController;
+import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
+
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a
* {@code view-controller} element to register a {@link ParameterizableViewController}.
+ * Will also register a {@link SimpleUrlHandlerMapping} for view controllers.
*
- * @author Rossen Stoyanchev
+ * @author Keith Donald
+ * @author Christian Dupuis
* @since 3.0
- * @see MvcViewControllers
- * @see MvcViewControllersExecutor
*/
-class ViewControllerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
+class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
- /**
- * Parses the {@code } tag.
- */
- public FeatureSpecification doParse(Element element, ParserContext parserContext) {
- String path = element.getAttribute("path");
- String viewName = element.getAttribute("view-name");
- return new MvcViewControllers(path, viewName.isEmpty() ? null : viewName);
+ private static final String HANDLER_ADAPTER_BEAN_NAME =
+ "org.springframework.web.servlet.config.viewControllerHandlerAdapter";
+
+ private static final String HANDLER_MAPPING_BEAN_NAME =
+ "org.springframework.web.servlet.config.viewControllerHandlerMapping";
+
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+
+ // Register handler adapter
+ registerHanderAdapter(parserContext, source);
+
+ // Register handler mapping
+ BeanDefinition handlerMappingDef = registerHandlerMapping(parserContext, source);
+
+ // Create view controller bean definition
+ RootBeanDefinition viewControllerDef = new RootBeanDefinition(ParameterizableViewController.class);
+ viewControllerDef.setSource(source);
+ if (element.hasAttribute("view-name")) {
+ viewControllerDef.getPropertyValues().add("viewName", element.getAttribute("view-name"));
+ }
+ Map urlMap;
+ if (handlerMappingDef.getPropertyValues().contains("urlMap")) {
+ urlMap = (Map) handlerMappingDef.getPropertyValues().getPropertyValue("urlMap").getValue();
+ }
+ else {
+ urlMap = new ManagedMap();
+ handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
+ }
+ urlMap.put(element.getAttribute("path"), viewControllerDef);
+ return null;
+ }
+
+ private void registerHanderAdapter(ParserContext parserContext, Object source) {
+ if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_ADAPTER_BEAN_NAME)) {
+ RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(SimpleControllerHandlerAdapter.class);
+ handlerAdapterDef.setSource(source);
+ handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ parserContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
+ parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
+ }
+ }
+
+ private BeanDefinition registerHandlerMapping(ParserContext parserContext, Object source) {
+ if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_BEAN_NAME)) {
+ RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
+ handlerMappingDef.setSource(source);
+ handlerMappingDef.getPropertyValues().add("order", "1");
+ handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
+ parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
+ return handlerMappingDef;
+ }
+ else {
+ return parserContext.getRegistry().getBeanDefinition(HANDLER_MAPPING_BEAN_NAME);
+ }
}
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcAnnotationDrivenFeatureTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcAnnotationDrivenFeatureTests.java
deleted file mode 100644
index 21fb0ae64f0..00000000000
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcAnnotationDrivenFeatureTests.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.springframework.beans.DirectFieldAccessor;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.format.support.DefaultFormattingConversionService;
-import org.springframework.format.support.FormattingConversionService;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.StringHttpMessageConverter;
-import org.springframework.validation.MessageCodesResolver;
-import org.springframework.validation.Validator;
-import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
-import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
-import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
-
-/**
- * Integration tests for the {@link MvcAnnotationDriven} feature specification.
- * @author Rossen Stoyanchev
- * @author Chris Beams
- * @since 3.1
- */
-public class MvcAnnotationDrivenFeatureTests {
-
- @SuppressWarnings("unchecked")
- @Test
- public void testMessageCodesResolver() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(MvcFeature.class, MvcBeans.class);
- ctx.refresh();
- RequestMappingHandlerMethodAdapter adapter = ctx.getBean(RequestMappingHandlerMethodAdapter.class);
- assertNotNull(adapter);
- Object initializer = new DirectFieldAccessor(adapter).getPropertyValue("webBindingInitializer");
- assertNotNull(initializer);
- MessageCodesResolver resolver = ((ConfigurableWebBindingInitializer) initializer).getMessageCodesResolver();
- assertNotNull(resolver);
- assertEquals("test.foo.bar", resolver.resolveMessageCodes("foo", "bar")[0]);
- Object value = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
- assertNotNull(value);
- List resolvers = (List) value;
- assertEquals(2, resolvers.size());
- assertTrue(resolvers.get(0) instanceof ServletWebArgumentResolverAdapter);
- assertTrue(resolvers.get(1) instanceof TestHandlerMethodArgumentResolver);
- Object converters = new DirectFieldAccessor(adapter).getPropertyValue("messageConverters");
- assertNotNull(converters);
- List> convertersArray = (List>) converters;
- assertTrue("Default converters are registered in addition to the custom one", convertersArray.size() > 1);
- assertTrue(convertersArray.get(0) instanceof StringHttpMessageConverter);
- }
-
-}
-
-@FeatureConfiguration
-class MvcFeature {
- @Feature
- public MvcAnnotationDriven annotationDriven(MvcBeans mvcBeans) {
- return new MvcAnnotationDriven()
- .conversionService(mvcBeans.conversionService())
- .messageCodesResolver(mvcBeans.messageCodesResolver())
- .validator(mvcBeans.validator())
- .messageConverters(new StringHttpMessageConverter())
- .argumentResolvers(new TestWebArgumentResolver())
- .argumentResolvers(new TestHandlerMethodArgumentResolver());
- }
-}
-
-@Configuration
-class MvcBeans {
- @Bean
- public FormattingConversionService conversionService() {
- return new DefaultFormattingConversionService();
- }
- @Bean
- public Validator validator() {
- return new LocalValidatorFactoryBean();
- }
- @Bean MessageCodesResolver messageCodesResolver() {
- return new TestMessageCodesResolver();
- }
-}
-
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerTests.java
deleted file mode 100644
index 74317c6bb88..00000000000
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerTests.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.springframework.beans.DirectFieldAccessor;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
-
-/**
- * Test fixture for {@link MvcDefaultServletHandler} feature specification.
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public class MvcDefaultServletHandlerTests {
-
- @Test
- public void testDefaultServletHandler() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(MvcDefaultServletHandlerFeature.class);
- ctx.refresh();
- HttpRequestHandlerAdapter adapter = ctx.getBean(HttpRequestHandlerAdapter.class);
- assertNotNull(adapter);
- DefaultServletHttpRequestHandler handler = ctx.getBean(DefaultServletHttpRequestHandler.class);
- assertNotNull(handler);
- String defaultServletHandlerName = (String) new DirectFieldAccessor(handler)
- .getPropertyValue("defaultServletName");
- assertEquals("foo", defaultServletHandlerName);
- }
-
- @FeatureConfiguration
- private static class MvcDefaultServletHandlerFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcDefaultServletHandler defaultServletHandler() {
- return new MvcDefaultServletHandler("foo");
- }
-
- }
-
-}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcInterceptorsTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcInterceptorsTests.java
deleted file mode 100644
index 6f3e42cf10b..00000000000
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcInterceptorsTests.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Iterator;
-
-import org.easymock.Capture;
-import org.junit.Test;
-import org.springframework.beans.factory.parsing.Problem;
-import org.springframework.beans.factory.parsing.ProblemReporter;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.web.servlet.HandlerInterceptor;
-import org.springframework.web.servlet.handler.MappedInterceptor;
-import org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor;
-import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
-import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
-
-/**
- * Test fixture for {@link MvcInterceptors}.
- * @author Rossen Stoyanchev
- */
-public class MvcInterceptorsTests {
-
- @Test
- public void testInterceptors() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(MvcInterceptorsFeature.class);
- ctx.refresh();
-
- Iterator itr = ctx.getBeansOfType(MappedInterceptor.class).values().iterator();
-
- MappedInterceptor interceptor = itr.next();
- assertTrue(interceptor.getInterceptor() instanceof UserRoleAuthorizationInterceptor);
- assertNull(interceptor.getPathPatterns());
-
- interceptor = itr.next();
- assertTrue(interceptor.getInterceptor() instanceof LocaleChangeInterceptor);
- assertArrayEquals(new String[] { "/locale", "/locale/**" }, interceptor.getPathPatterns());
-
- interceptor = itr.next();
- assertTrue(interceptor.getInterceptor() instanceof ThemeChangeInterceptor);
- assertArrayEquals(new String[] { "/theme", "/theme/**" }, interceptor.getPathPatterns());
-
- }
-
- @Test
- public void validateNoInterceptors() {
- ProblemReporter reporter = createMock(ProblemReporter.class);
- Capture captured = new Capture();
- reporter.error(capture(captured));
- replay(reporter);
-
- boolean result = new MvcInterceptors().validate(reporter);
-
- assertFalse(result);
- assertEquals("No interceptors defined.", captured.getValue().getMessage());
- }
-
- @Test
- public void validateNullHandler() {
- ProblemReporter reporter = createMock(ProblemReporter.class);
- Capture captured = new Capture();
- reporter.error(capture(captured));
- replay(reporter);
-
- HandlerInterceptor[] interceptors = new HandlerInterceptor[] { null };
- boolean result = new MvcInterceptors().globalInterceptors(interceptors).validate(reporter);
-
- assertFalse(result);
- assertTrue(captured.getValue().getMessage().contains("Null interceptor"));
- }
-
- @Test
- public void validateEmptyPath() {
- ProblemReporter reporter = createMock(ProblemReporter.class);
- Capture captured = new Capture();
- reporter.error(capture(captured));
- replay(reporter);
-
- HandlerInterceptor[] interceptors = new HandlerInterceptor[] { new LocaleChangeInterceptor() };
- String[] patterns = new String[] { "" };
- boolean result = new MvcInterceptors().mappedInterceptors(patterns, interceptors).validate(reporter);
-
- assertFalse(result);
- assertTrue(captured.getValue().getMessage().startsWith("Empty path pattern specified for "));
- }
-
- @FeatureConfiguration
- private static class MvcInterceptorsFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcInterceptors interceptors() {
- return new MvcInterceptors()
- .globalInterceptors(new UserRoleAuthorizationInterceptor())
- .mappedInterceptors(new String[] { "/locale", "/locale/**" }, new LocaleChangeInterceptor())
- .mappedInterceptors(new String[] { "/theme", "/theme/**"}, new ThemeChangeInterceptor());
- }
-
- }
-
-}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcResourcesTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcResourcesTests.java
deleted file mode 100644
index bf71da49afa..00000000000
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcResourcesTests.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.springframework.beans.DirectFieldAccessor;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.core.io.Resource;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
-import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
-
-/**
- * Test fixture for {@link MvcResources} feature specification.
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public class MvcResourcesTests {
-
- @Test
- public void testResources() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(MvcResourcesFeature.class);
- ctx.refresh();
- HttpRequestHandlerAdapter adapter = ctx.getBean(HttpRequestHandlerAdapter.class);
- assertNotNull(adapter);
- ResourceHttpRequestHandler handler = ctx.getBean(ResourceHttpRequestHandler.class);
- assertNotNull(handler);
- @SuppressWarnings("unchecked")
- List locations = (List) new DirectFieldAccessor(handler).getPropertyValue("locations");
- assertNotNull(locations);
- assertEquals(2, locations.size());
- assertEquals("foo", locations.get(0).getFilename());
- assertEquals("bar", locations.get(1).getFilename());
- SimpleUrlHandlerMapping mapping = ctx.getBean(SimpleUrlHandlerMapping.class);
- assertEquals(1, mapping.getOrder());
- assertSame(handler, mapping.getHandlerMap().get("/resources/**"));
- }
-
- @Test
- public void testInvalidResources() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(InvalidMvcResourcesFeature.class);
- try {
- ctx.refresh();
- fail("Invalid feature spec should not validate");
- } catch (RuntimeException e) {
- assertTrue(e.getCause().getMessage().contains("Mapping is required"));
- // TODO : should all problems be in the message ?
- }
- }
-
- @FeatureConfiguration
- private static class MvcResourcesFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcResources resources() {
- return new MvcResources("/resources/**", new String[] { "/foo", "/bar" }).cachePeriod(86400).order(1);
- }
-
- }
-
- @FeatureConfiguration
- private static class InvalidMvcResourcesFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcResources resources() {
- return new MvcResources(" ", new String[] {});
- }
-
- }
-
-}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcViewControllersTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcViewControllersTests.java
deleted file mode 100644
index fdb27d71557..00000000000
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcViewControllersTests.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.web.servlet.config;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.springframework.beans.factory.parsing.FailFastProblemReporter;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Feature;
-import org.springframework.context.annotation.FeatureConfiguration;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
-
-/**
- * Test fixture for {@link MvcViewControllers} feature specification.
- * @author Rossen Stoyanchev
- * @since 3.1
- */
-public class MvcViewControllersTests {
-
- @Test
- public void testMvcViewControllers() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(MvcViewControllersFeature.class);
- ctx.refresh();
- SimpleControllerHandlerAdapter adapter = ctx.getBean(SimpleControllerHandlerAdapter.class);
- assertNotNull(adapter);
- SimpleUrlHandlerMapping handler = ctx.getBean(SimpleUrlHandlerMapping.class);
- assertNotNull(handler);
- Map urlMap = handler.getUrlMap();
- assertNotNull(urlMap);
- assertEquals(2, urlMap.size());
- ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/");
- assertNotNull(controller);
- assertEquals("home", controller.getViewName());
- controller = (ParameterizableViewController) urlMap.get("/account");
- assertNotNull(controller);
- assertNull(controller.getViewName());
- }
-
- @Test
- public void testEmptyPath() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(EmptyPathViewControllersFeature.class);
- try {
- ctx.refresh();
- fail("expected exception");
- } catch (Exception ex) {
- assertTrue(ex.getCause().getMessage().contains("path attribute"));
- }
- }
-
- @Test
- public void testEmptyViewName() {
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(EmptyViewNameViewControllersFeature.class);
- try {
- ctx.refresh();
- fail("expected exception");
- } catch (Exception ex) {
- assertTrue(ex.getCause().getMessage().contains("not empty"));
- }
- }
-
- @Test
- public void testNullViewName() {
- FailFastProblemReporter problemReporter = new FailFastProblemReporter();
- assertThat(new MvcViewControllers("/some/path").validate(problemReporter), is(true));
- }
-
-
- @FeatureConfiguration
- private static class MvcViewControllersFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcViewControllers mvcViewControllers() {
- return new MvcViewControllers("/", "home").viewController("/account");
- }
-
- }
-
-
- @FeatureConfiguration
- private static class EmptyViewNameViewControllersFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcViewControllers mvcViewControllers() {
- return new MvcViewControllers("/some/path", "");
- }
-
- }
-
-
- @FeatureConfiguration
- private static class EmptyPathViewControllersFeature {
-
- @SuppressWarnings("unused")
- @Feature
- public MvcViewControllers mvcViewControllers() {
- return new MvcViewControllers("", "someViewName");
- }
-
- }
-
-}
-