Introduce FeatureSpecification support
Introduce FeatureSpecification interface and implementations
FeatureSpecification objects decouple the configuration of
spring container features from the concern of parsing XML
namespaces, allowing for reuse in code-based configuration
(see @Feature* annotations below).
* ComponentScanSpec
* TxAnnotationDriven
* MvcAnnotationDriven
* MvcDefaultServletHandler
* MvcResources
* MvcViewControllers
Refactor associated BeanDefinitionParsers to delegate to new impls above
The following BeanDefinitionParser implementations now deal only
with the concern of XML parsing. Validation is handled by their
corresponding FeatureSpecification object. Bean definition creation
and registration is handled by their corresponding
FeatureSpecificationExecutor type.
* ComponentScanBeanDefinitionParser
* AnnotationDrivenBeanDefinitionParser (tx)
* AnnotationDrivenBeanDefinitionParser (mvc)
* DefaultServletHandlerBeanDefinitionParser
* ResourcesBeanDefinitionParser
* ViewControllerBeanDefinitionParser
Update AopNamespaceUtils to decouple from XML (DOM API)
Methods necessary for executing TxAnnotationDriven specification
(and eventually, the AspectJAutoProxy specification) have been
added that accept boolean arguments for whether to proxy
target classes and whether to expose the proxy via threadlocal.
Methods that accepted and introspected DOM Element objects still
exist but have been deprecated.
Introduce @FeatureConfiguration classes and @Feature methods
Allow for creation and configuration of FeatureSpecification objects
at the user level. A companion for @Configuration classes allowing
for completely code-driven configuration of the Spring container.
See changes in ConfigurationClassPostProcessor for implementation
details.
See Feature*Tests for usage examples.
FeatureTestSuite in .integration-tests is a JUnit test suite designed
to aggregate all BDP and Feature* related tests for a convenient way
to confirm that Feature-related changes don't break anything.
Uncomment this test and execute from Eclipse / IDEA. Due to classpath
issues, this cannot be compiled by Ant/Ivy at the command line.
Introduce @FeatureAnnotation meta-annotation and @ComponentScan impl
@FeatureAnnotation provides an alternate mechanism for creating
and executing FeatureSpecification objects. See @ComponentScan
and its corresponding ComponentScanAnnotationParser implementation
for details. See ComponentScanAnnotationIntegrationTests for usage
examples
Introduce Default[Formatting]ConversionService implementations
Allows for convenient instantiation of ConversionService objects
containing defaults appropriate for most environments. Replaces
similar support originally in ConversionServiceFactory (which is now
deprecated). This change was justified by the need to avoid use
of FactoryBeans in @Configuration classes (such as
FormattingConversionServiceFactoryBean). It is strongly preferred
that users simply instantiate and configure the objects that underlie
our FactoryBeans. In the case of the ConversionService types, the
easiest way to do this is to create Default* subtypes. This also
follows convention with the rest of the framework.
Minor updates to util classes
All in service of changes above. See diffs for self-explanatory
details.
* BeanUtils
* ObjectUtils
* ReflectionUtils
This commit is contained in:
@@ -86,7 +86,7 @@ public abstract class BeanUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to instantiate a class using its no-arg constructor.
|
||||
* Instantiate a class using its no-arg constructor.
|
||||
* As this method doesn't try to load classes by name, it should avoid
|
||||
* class-loading issues.
|
||||
* <p>Note that this method tries to set the constructor accessible
|
||||
@@ -108,6 +108,27 @@ public abstract class BeanUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a class using its no-arg constructor and return the new instance
|
||||
* as the the specified assignable type.
|
||||
* <p>Useful in cases where
|
||||
* the type of the class to instantiate (clazz) is not available, but the type
|
||||
* desired (assignableTo) is known.
|
||||
* <p>As this method doesn't try to load classes by name, it should avoid
|
||||
* class-loading issues.
|
||||
* <p>Note that this method tries to set the constructor accessible
|
||||
* if given a non-accessible (that is, non-public) constructor.
|
||||
* @param clazz class to instantiate
|
||||
* @param assignableTo type that clazz must be assignableTo
|
||||
* @return the new instance
|
||||
* @throws BeanInstantiationException if the bean cannot be instantiated
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T instantiateClass(Class<?> clazz, Class<T> assignableTo) throws BeanInstantiationException {
|
||||
Assert.isAssignable(assignableTo, clazz);
|
||||
return (T)instantiateClass(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to instantiate a class using the given constructor.
|
||||
* As this method doesn't try to load classes by name, it should avoid
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public interface BeanDefinitionRegistrar {
|
||||
|
||||
String registerWithGeneratedName(BeanDefinition beanDefinition);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public interface ComponentRegistrar extends BeanDefinitionRegistrar {
|
||||
|
||||
void registerBeanComponent(BeanComponentDefinition component);
|
||||
|
||||
void registerComponent(ComponentDefinition component);
|
||||
}
|
||||
@@ -30,12 +30,13 @@ public class ReaderContext {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
private final ProblemReporter problemReporter;
|
||||
|
||||
private final ReaderEventListener eventListener;
|
||||
|
||||
private final SourceExtractor sourceExtractor;
|
||||
|
||||
// TODO SPR-7420: review exposing problem reporter
|
||||
protected final ProblemReporter problemReporter;
|
||||
|
||||
|
||||
public ReaderContext(Resource resource, ProblemReporter problemReporter,
|
||||
ReaderEventListener eventListener, SourceExtractor sourceExtractor) {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
private Location location = null;
|
||||
private List<Problem> errors = new ArrayList<Problem>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -166,7 +166,7 @@ public class BeanDefinitionReaderUtils {
|
||||
* for the given bean definition or the definition cannot be registered
|
||||
*/
|
||||
public static String registerWithGeneratedName(
|
||||
AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
|
||||
BeanDefinition definition, BeanDefinitionRegistry registry)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String generatedName = generateBeanName(definition, registry, false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,8 @@ import org.w3c.dom.Element;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
||||
/**
|
||||
* Interface used by the
|
||||
* {@link org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader} to
|
||||
* handle custom, top-level (directly under <code><beans></code>) tags.
|
||||
* Interface used by the {@link DefaultBeanDefinitionDocumentReader} to handle custom,
|
||||
* top-level (directly under {@code <beans>}) tags.
|
||||
*
|
||||
* <p>Implementations are free to turn the metadata in the custom tag into as many
|
||||
* {@link BeanDefinition BeanDefinitions} as required.
|
||||
@@ -31,11 +30,19 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
* <p>The parser locates a {@link BeanDefinitionParser} from the associated
|
||||
* {@link NamespaceHandler} for the namespace in which the custom tag resides.
|
||||
*
|
||||
* <p>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 org.springframework.beans.factory.xml.BeanDefinitionDecorator
|
||||
* @see AbstractBeanDefinitionParser
|
||||
* @see org.springframework.beans.factory.xml.BeanDefinitionDecorator
|
||||
* @see org.springframework.context.FeatureSpecification
|
||||
* @see org.springframework.context.AbstractSpecificationExecutor
|
||||
*/
|
||||
public interface BeanDefinitionParser {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Stack;
|
||||
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.parsing.CompositeComponentDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
@@ -36,7 +37,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
* @see XmlReaderContext
|
||||
* @see BeanDefinitionParserDelegate
|
||||
*/
|
||||
public final class ParserContext {
|
||||
public final class ParserContext implements ComponentRegistrar {
|
||||
|
||||
private final XmlReaderContext readerContext;
|
||||
|
||||
@@ -121,4 +122,8 @@ public final class ParserContext {
|
||||
registerComponent(component);
|
||||
}
|
||||
|
||||
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
|
||||
return this.readerContext.registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,4 +83,9 @@ public class XmlReaderContext extends ReaderContext {
|
||||
return generatedName;
|
||||
}
|
||||
|
||||
// TODO SPR-7420: review exposing problem reporter
|
||||
public ProblemReporter getProblemReporter() {
|
||||
return this.problemReporter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user