Added ASPECTJ and REGEX constants to FilterType, along with a corresponding 'pattern' attribute on ComponentScan.Filter
Issue: SPR-10593
This commit is contained in:
@@ -42,9 +42,10 @@ import org.springframework.core.type.filter.TypeFilter;
|
||||
* always registered, meaning that any attempt to disable them at the
|
||||
* {@code @ComponentScan} level would be ignored.
|
||||
*
|
||||
* <p>See @{@link Configuration} Javadoc for usage examples.
|
||||
* <p>See @{@link Configuration}'s javadoc for usage examples.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see Configuration
|
||||
*/
|
||||
@@ -139,31 +140,33 @@ public @interface ComponentScan {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({})
|
||||
@interface Filter {
|
||||
|
||||
/**
|
||||
* The type of filter to use.
|
||||
* <p>Note that the filter types available are limited to those that may
|
||||
* be expressed as a {@code Class} in the {@link #value()} attribute. This is
|
||||
* in contrast to {@code <context:component-scan/>}, which allows for
|
||||
* expression-based (i.e., string-based) filters such as AspectJ pointcuts.
|
||||
* These filter types are intentionally not supported here, and not available
|
||||
* in the {@link FilterType} enum.
|
||||
* @see FilterType
|
||||
*/
|
||||
FilterType type() default FilterType.ANNOTATION;
|
||||
|
||||
/**
|
||||
* The class or classes to use as the filter. In the case of
|
||||
* {@link FilterType#ANNOTATION}, the class will be the annotation itself. In the
|
||||
* case of {@link FilterType#ASSIGNABLE_TYPE}, the class will be the type that
|
||||
* detected components should be assignable to. And in the case of
|
||||
* {@link FilterType#CUSTOM}, the class will be an implementation of
|
||||
* {@link FilterType#ANNOTATION}, the class will be the annotation itself.
|
||||
* In the case of {@link FilterType#ASSIGNABLE_TYPE}, the class will be the
|
||||
* type that detected components should be assignable to. And in the case
|
||||
* of {@link FilterType#CUSTOM}, the class will be an implementation of
|
||||
* {@link TypeFilter}.
|
||||
* <p>When multiple classes are specified, OR logic is applied, e.g. "include
|
||||
* types annotated with {@code @Foo} OR {@code @Bar}".
|
||||
* <p>Specifying zero classes is permitted but will have no effect on component
|
||||
* scanning.
|
||||
*/
|
||||
Class<?>[] value();
|
||||
Class<?>[] value() default {};
|
||||
|
||||
/**
|
||||
* The String pattern (or patterns) to use for the filter, as an alternative to
|
||||
* specifying a Class {@link #value()}. In the case of {@link FilterType#ASPECTJ},
|
||||
* this is an AspectJ type pattern expression; in case of {@link FilterType#REGEX},
|
||||
* a regex pattern for the fully-qualified class names to match.
|
||||
*/
|
||||
String[] pattern() default {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
@@ -30,7 +31,9 @@ import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter;
|
||||
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.ClassUtils;
|
||||
@@ -40,6 +43,7 @@ import org.springframework.util.StringUtils;
|
||||
* Parser for the @{@link ComponentScan} annotation.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see ClassPathBeanDefinitionScanner#scan(String...)
|
||||
* @see ComponentScanBeanDefinitionParser
|
||||
@@ -138,25 +142,37 @@ class ComponentScanAnnotationParser {
|
||||
switch (filterType) {
|
||||
case ANNOTATION:
|
||||
Assert.isAssignable(Annotation.class, filterClass,
|
||||
"An error occured when processing a @ComponentScan " +
|
||||
"ANNOTATION type filter: ");
|
||||
"An error occured while processing a @ComponentScan ANNOTATION type filter: ");
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Annotation> annoClass = (Class<Annotation>)filterClass;
|
||||
typeFilters.add(new AnnotationTypeFilter(annoClass));
|
||||
Class<Annotation> annotationType = (Class<Annotation>) filterClass;
|
||||
typeFilters.add(new AnnotationTypeFilter(annotationType));
|
||||
break;
|
||||
case ASSIGNABLE_TYPE:
|
||||
typeFilters.add(new AssignableTypeFilter(filterClass));
|
||||
break;
|
||||
case CUSTOM:
|
||||
Assert.isAssignable(TypeFilter.class, filterClass,
|
||||
"An error occured when processing a @ComponentScan " +
|
||||
"CUSTOM type filter: ");
|
||||
"An error occured while processing a @ComponentScan CUSTOM type filter: ");
|
||||
typeFilters.add(BeanUtils.instantiateClass(filterClass, TypeFilter.class));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown filter type " + filterType);
|
||||
throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType);
|
||||
}
|
||||
}
|
||||
|
||||
for (String expression : filterAttributes.getStringArray("pattern")) {
|
||||
switch (filterType) {
|
||||
case ASPECTJ:
|
||||
typeFilters.add(new AspectJTypeFilter(expression, this.resourceLoader.getClassLoader()));
|
||||
break;
|
||||
case REGEX:
|
||||
typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression)));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType);
|
||||
}
|
||||
}
|
||||
|
||||
return typeFilters;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 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,9 +16,6 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration of the type filters that may be used in conjunction with
|
||||
* {@link ComponentScan @ComponentScan}.
|
||||
@@ -42,12 +39,24 @@ public enum FilterType {
|
||||
|
||||
/**
|
||||
* Filter candidates assignable to a given type.
|
||||
* @see AssignableTypeFilter
|
||||
* @see org.springframework.core.type.filter.AssignableTypeFilter
|
||||
*/
|
||||
ASSIGNABLE_TYPE,
|
||||
|
||||
/**
|
||||
* Filter candidates matching a given AspectJ type pattern expression.
|
||||
* @see org.springframework.core.type.filter.AspectJTypeFilter
|
||||
*/
|
||||
ASPECTJ,
|
||||
|
||||
/**
|
||||
* Filter candidates matching a given regex pattern.
|
||||
* @see org.springframework.core.type.filter.RegexPatternTypeFilter
|
||||
*/
|
||||
REGEX,
|
||||
|
||||
/** Filter candidates using a given custom
|
||||
* {@link org.springframework.core.type.filter.TypeFilter} implementation
|
||||
* {@link org.springframework.core.type.filter.TypeFilter} implementation.
|
||||
*/
|
||||
CUSTOM
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -109,7 +109,7 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" />
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -161,13 +161,13 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer" />
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="propertyPlaceholder" />
|
||||
<xsd:extension base="propertyPlaceholder"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
@@ -275,9 +275,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.beans.factory.support.BeanNameGenerator" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.beans.factory.support.BeanNameGenerator"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -290,9 +289,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.context.annotation.ScopeMetadataResolver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.context.annotation.ScopeMetadataResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -306,9 +304,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="no" />
|
||||
<xsd:enumeration value="interfaces" />
|
||||
<xsd:enumeration value="targetClass" />
|
||||
<xsd:enumeration value="no"/>
|
||||
<xsd:enumeration value="interfaces"/>
|
||||
<xsd:enumeration value="targetClass"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -344,8 +342,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:exports type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -357,9 +354,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -407,7 +403,7 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string" />
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -423,8 +419,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
|
||||
<tool:exports type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -457,9 +452,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:NMTOKEN">
|
||||
<xsd:enumeration value="failOnExisting" />
|
||||
<xsd:enumeration value="ignoreExisting" />
|
||||
<xsd:enumeration value="replaceExisting" />
|
||||
<xsd:enumeration value="failOnExisting"/>
|
||||
<xsd:enumeration value="ignoreExisting"/>
|
||||
<xsd:enumeration value="replaceExisting"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -478,7 +473,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="javax.management.MBeanServer" />
|
||||
<tool:exports type="javax.management.MBeanServer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -505,8 +500,8 @@
|
||||
|
||||
"annotation" indicates an annotation to be present at the type level in target components;
|
||||
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
|
||||
"aspectj" indicates an AspectJ type expression to be matched by the target components;
|
||||
"regex" indicates a regex expression to be matched by the target components' class names;
|
||||
"aspectj" indicates an AspectJ type pattern expression to be matched by the target components;
|
||||
"regex" indicates a regex pattern to be matched by the target components' class names;
|
||||
"custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
|
||||
|
||||
Note: This attribute will not be inherited by child bean definitions.
|
||||
@@ -515,11 +510,11 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="annotation" />
|
||||
<xsd:enumeration value="assignable" />
|
||||
<xsd:enumeration value="aspectj" />
|
||||
<xsd:enumeration value="regex" />
|
||||
<xsd:enumeration value="custom" />
|
||||
<xsd:enumeration value="annotation"/>
|
||||
<xsd:enumeration value="assignable"/>
|
||||
<xsd:enumeration value="aspectj"/>
|
||||
<xsd:enumeration value="regex"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.2.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.2.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -109,7 +109,7 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" />
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -161,13 +161,13 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer" />
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="propertyPlaceholder" />
|
||||
<xsd:extension base="propertyPlaceholder"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
@@ -275,9 +275,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.beans.factory.support.BeanNameGenerator" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.beans.factory.support.BeanNameGenerator"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -290,9 +289,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.context.annotation.ScopeMetadataResolver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.context.annotation.ScopeMetadataResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -306,9 +304,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="no" />
|
||||
<xsd:enumeration value="interfaces" />
|
||||
<xsd:enumeration value="targetClass" />
|
||||
<xsd:enumeration value="no"/>
|
||||
<xsd:enumeration value="interfaces"/>
|
||||
<xsd:enumeration value="targetClass"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -344,8 +342,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:exports type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -357,9 +354,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -407,7 +403,7 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string" />
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -423,8 +419,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
|
||||
<tool:exports type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -457,9 +452,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:NMTOKEN">
|
||||
<xsd:enumeration value="failOnExisting" />
|
||||
<xsd:enumeration value="ignoreExisting" />
|
||||
<xsd:enumeration value="replaceExisting" />
|
||||
<xsd:enumeration value="failOnExisting"/>
|
||||
<xsd:enumeration value="ignoreExisting"/>
|
||||
<xsd:enumeration value="replaceExisting"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -478,7 +473,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="javax.management.MBeanServer" />
|
||||
<tool:exports type="javax.management.MBeanServer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -505,8 +500,8 @@
|
||||
|
||||
"annotation" indicates an annotation to be present at the type level in target components;
|
||||
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
|
||||
"aspectj" indicates an AspectJ type expression to be matched by the target components;
|
||||
"regex" indicates a regex expression to be matched by the target components' class names;
|
||||
"aspectj" indicates an AspectJ type pattern expression to be matched by the target components;
|
||||
"regex" indicates a regex pattern to be matched by the target components' class names;
|
||||
"custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
|
||||
|
||||
Note: This attribute will not be inherited by child bean definitions.
|
||||
@@ -515,11 +510,11 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="annotation" />
|
||||
<xsd:enumeration value="assignable" />
|
||||
<xsd:enumeration value="aspectj" />
|
||||
<xsd:enumeration value="regex" />
|
||||
<xsd:enumeration value="custom" />
|
||||
<xsd:enumeration value="annotation"/>
|
||||
<xsd:enumeration value="assignable"/>
|
||||
<xsd:enumeration value="aspectj"/>
|
||||
<xsd:enumeration value="regex"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.0.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.0.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.0.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -109,7 +109,7 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" />
|
||||
type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -161,13 +161,13 @@
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer" />
|
||||
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="propertyPlaceholder" />
|
||||
<xsd:extension base="propertyPlaceholder"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
@@ -275,9 +275,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.beans.factory.support.BeanNameGenerator" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.beans.factory.support.BeanNameGenerator"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -290,9 +289,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.context.annotation.ScopeMetadataResolver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.context.annotation.ScopeMetadataResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -306,9 +304,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="no" />
|
||||
<xsd:enumeration value="interfaces" />
|
||||
<xsd:enumeration value="targetClass" />
|
||||
<xsd:enumeration value="no"/>
|
||||
<xsd:enumeration value="interfaces"/>
|
||||
<xsd:enumeration value="targetClass"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -342,8 +340,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:exports type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -355,9 +352,8 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -405,7 +401,7 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string" />
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -421,8 +417,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports
|
||||
type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
|
||||
<tool:exports type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -455,9 +450,9 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:NMTOKEN">
|
||||
<xsd:enumeration value="failOnExisting" />
|
||||
<xsd:enumeration value="ignoreExisting" />
|
||||
<xsd:enumeration value="replaceExisting" />
|
||||
<xsd:enumeration value="failOnExisting"/>
|
||||
<xsd:enumeration value="ignoreExisting"/>
|
||||
<xsd:enumeration value="replaceExisting"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
@@ -476,7 +471,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="javax.management.MBeanServer" />
|
||||
<tool:exports type="javax.management.MBeanServer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -503,8 +498,8 @@
|
||||
|
||||
"annotation" indicates an annotation to be present at the type level in target components;
|
||||
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
|
||||
"aspectj" indicates an AspectJ type expression to be matched by the target components;
|
||||
"regex" indicates a regex expression to be matched by the target components' class names;
|
||||
"aspectj" indicates an AspectJ type pattern expression to be matched by the target components;
|
||||
"regex" indicates a regex pattern to be matched by the target components' class names;
|
||||
"custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
|
||||
|
||||
Note: This attribute will not be inherited by child bean definitions.
|
||||
@@ -513,11 +508,11 @@
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="annotation" />
|
||||
<xsd:enumeration value="assignable" />
|
||||
<xsd:enumeration value="aspectj" />
|
||||
<xsd:enumeration value="regex" />
|
||||
<xsd:enumeration value="custom" />
|
||||
<xsd:enumeration value="annotation"/>
|
||||
<xsd:enumeration value="assignable"/>
|
||||
<xsd:enumeration value="aspectj"/>
|
||||
<xsd:enumeration value="regex"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -16,18 +16,20 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
|
||||
import example.scannable.CustomComponent;
|
||||
import example.scannable.CustomStereotype;
|
||||
import example.scannable.DefaultNamedComponent;
|
||||
import example.scannable.FooService;
|
||||
import example.scannable.MessageBean;
|
||||
import example.scannable.ScopedProxyTestBean;
|
||||
import example.scannable_implicitbasepackage.ComponentScanAnnotatedConfigWithImplicitBasePackage;
|
||||
import example.scannable_scoped.CustomScopeAnnotationBean;
|
||||
import example.scannable_scoped.MyScope;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -39,24 +41,19 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.tests.context.SimpleMapScope;
|
||||
import org.springframework.util.SerializationTestUtils;
|
||||
|
||||
import example.scannable.CustomComponent;
|
||||
import example.scannable.CustomStereotype;
|
||||
import example.scannable.DefaultNamedComponent;
|
||||
import example.scannable.FooService;
|
||||
import example.scannable.MessageBean;
|
||||
import example.scannable.ScopedProxyTestBean;
|
||||
import example.scannable_implicitbasepackage.ComponentScanAnnotatedConfigWithImplicitBasePackage;
|
||||
import example.scannable_scoped.CustomScopeAnnotationBean;
|
||||
import example.scannable_scoped.MyScope;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
/**
|
||||
* Integration tests for processing ComponentScan-annotated Configuration
|
||||
* classes.
|
||||
* Integration tests for processing ComponentScan-annotated Configuration classes.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ComponentScanAnnotationIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void controlScan() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -162,6 +159,30 @@ public class ComponentScanAnnotationIntegrationTests {
|
||||
assertThat(deserialized.foo(1), equalTo("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withScopedProxyThroughRegex() throws IOException, ClassNotFoundException {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ComponentScanWithScopedProxyThroughRegex.class);
|
||||
ctx.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
ctx.refresh();
|
||||
// should cast to the interface
|
||||
FooService bean = (FooService) ctx.getBean("scopedProxyTestBean");
|
||||
// should be dynamic proxy
|
||||
assertThat(AopUtils.isJdkDynamicProxy(bean), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withScopedProxyThroughAspectJPattern() throws IOException, ClassNotFoundException {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ComponentScanWithScopedProxyThroughAspectJPattern.class);
|
||||
ctx.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
ctx.refresh();
|
||||
// should cast to the interface
|
||||
FooService bean = (FooService) ctx.getBean("scopedProxyTestBean");
|
||||
// should be dynamic proxy
|
||||
assertThat(AopUtils.isJdkDynamicProxy(bean), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withMultipleAnnotationIncludeFilters1() throws IOException, ClassNotFoundException {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -211,11 +232,11 @@ class ComponentScanAnnotatedConfig_WithValueAttribute {
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
class ComponentScanWithNoPackagesConfig { }
|
||||
class ComponentScanWithNoPackagesConfig {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable", nameGenerator=MyBeanNameGenerator.class)
|
||||
class ComponentScanWithBeanNameGenenerator { }
|
||||
class ComponentScanWithBeanNameGenenerator {}
|
||||
|
||||
class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
|
||||
@Override
|
||||
@@ -226,7 +247,7 @@ class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable_scoped", scopeResolver=MyScopeMetadataResolver.class)
|
||||
class ComponentScanWithScopeResolver { }
|
||||
class ComponentScanWithScopeResolver {}
|
||||
|
||||
class MyScopeMetadataResolver extends AnnotationScopeMetadataResolver {
|
||||
MyScopeMetadataResolver() {
|
||||
@@ -259,7 +280,21 @@ class ComponentScanWithCustomTypeFilter {
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, value=ScopedProxyTestBean.class))
|
||||
class ComponentScanWithScopedProxy { }
|
||||
class ComponentScanWithScopedProxy {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter(type=FilterType.REGEX, pattern ="((?:[a-z.]+))ScopedProxyTestBean"))
|
||||
class ComponentScanWithScopedProxyThroughRegex {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter(type=FilterType.ASPECTJ, pattern ="*..ScopedProxyTestBean"))
|
||||
class ComponentScanWithScopedProxyThroughAspectJPattern {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
@@ -269,18 +304,18 @@ class ComponentScanWithScopedProxy { }
|
||||
@Filter(CustomComponent.class)
|
||||
}
|
||||
)
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters1 { }
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters1 {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter({CustomStereotype.class, CustomComponent.class})
|
||||
)
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters2 { }
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters2 {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
value="example.scannable",
|
||||
basePackages="example.scannable",
|
||||
basePackageClasses=example.scannable._package.class)
|
||||
class ComponentScanWithBasePackagesAndValueAlias { }
|
||||
class ComponentScanWithBasePackagesAndValueAlias {}
|
||||
|
||||
Reference in New Issue
Block a user