Merge branch '5.3.x'
This commit is contained in:
commit
71036e7da5
|
|
@ -16,13 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
|
|
@ -33,12 +30,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter;
|
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.core.type.filter.TypeFilter;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
|
@ -93,13 +85,17 @@ class ComponentScanAnnotationParser {
|
||||||
|
|
||||||
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
|
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
|
||||||
|
|
||||||
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
|
for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
|
||||||
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
|
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
|
||||||
|
this.resourceLoader, this.registry);
|
||||||
|
for (TypeFilter typeFilter : typeFilters) {
|
||||||
scanner.addIncludeFilter(typeFilter);
|
scanner.addIncludeFilter(typeFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
|
for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
|
||||||
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
|
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
|
||||||
|
this.resourceLoader, this.registry);
|
||||||
|
for (TypeFilter typeFilter : typeFilters) {
|
||||||
scanner.addExcludeFilter(typeFilter);
|
scanner.addExcludeFilter(typeFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -132,49 +128,4 @@ class ComponentScanAnnotationParser {
|
||||||
return scanner.doScan(StringUtils.toStringArray(basePackages));
|
return scanner.doScan(StringUtils.toStringArray(basePackages));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) {
|
|
||||||
List<TypeFilter> typeFilters = new ArrayList<>();
|
|
||||||
FilterType filterType = filterAttributes.getEnum("type");
|
|
||||||
|
|
||||||
for (Class<?> filterClass : filterAttributes.getClassArray("classes")) {
|
|
||||||
switch (filterType) {
|
|
||||||
case ANNOTATION:
|
|
||||||
Assert.isAssignable(Annotation.class, filterClass,
|
|
||||||
"@ComponentScan ANNOTATION type filter requires an annotation type");
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
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,
|
|
||||||
"@ComponentScan CUSTOM type filter requires a TypeFilter implementation");
|
|
||||||
|
|
||||||
TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class,
|
|
||||||
this.environment, this.resourceLoader, this.registry);
|
|
||||||
typeFilters.add(filter);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2021 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
|
||||||
|
*
|
||||||
|
* https://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.Annotation;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.core.annotation.AnnotationAttributes;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of utilities for working with {@link ComponentScan @ComponentScan}
|
||||||
|
* {@linkplain ComponentScan.Filter type filters}.
|
||||||
|
*
|
||||||
|
* @author Chris Beams
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
|
* @since 5.3.13
|
||||||
|
* @see ComponentScan.Filter
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
*/
|
||||||
|
public abstract class TypeFilterUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create {@linkplain TypeFilter type filters} from the supplied
|
||||||
|
* {@link AnnotationAttributes}, such as those sourced from
|
||||||
|
* {@link ComponentScan#includeFilters()} or {@link ComponentScan#excludeFilters()}.
|
||||||
|
* <p>Each {@link TypeFilter} will be instantiated using an appropriate
|
||||||
|
* constructor, with {@code BeanClassLoaderAware}, {@code BeanFactoryAware},
|
||||||
|
* {@code EnvironmentAware}, and {@code ResourceLoaderAware} contracts
|
||||||
|
* invoked if they are implemented by the type filter.
|
||||||
|
* @param filterAttributes {@code AnnotationAttributes} for a
|
||||||
|
* {@link ComponentScan.Filter @Filter} declaration
|
||||||
|
* @param environment the {@code Environment} to make available to filters
|
||||||
|
* @param resourceLoader the {@code ResourceLoader} to make available to filters
|
||||||
|
* @param registry the {@code BeanDefinitionRegistry} to make available to filters
|
||||||
|
* as a {@link org.springframework.beans.factory.BeanFactory} if applicable
|
||||||
|
* @return a list of instantiated and configured type filters
|
||||||
|
* @see TypeFilter
|
||||||
|
* @see AnnotationTypeFilter
|
||||||
|
* @see AssignableTypeFilter
|
||||||
|
* @see AspectJTypeFilter
|
||||||
|
* @see RegexPatternTypeFilter
|
||||||
|
* @see org.springframework.beans.factory.BeanClassLoaderAware
|
||||||
|
* @see org.springframework.beans.factory.BeanFactoryAware
|
||||||
|
* @see org.springframework.context.EnvironmentAware
|
||||||
|
* @see org.springframework.context.ResourceLoaderAware
|
||||||
|
*/
|
||||||
|
public static List<TypeFilter> createTypeFiltersFor(AnnotationAttributes filterAttributes, Environment environment,
|
||||||
|
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
|
||||||
|
|
||||||
|
List<TypeFilter> typeFilters = new ArrayList<>();
|
||||||
|
FilterType filterType = filterAttributes.getEnum("type");
|
||||||
|
|
||||||
|
for (Class<?> filterClass : filterAttributes.getClassArray("classes")) {
|
||||||
|
switch (filterType) {
|
||||||
|
case ANNOTATION:
|
||||||
|
Assert.isAssignable(Annotation.class, filterClass,
|
||||||
|
"@ComponentScan ANNOTATION type filter requires an annotation type");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
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,
|
||||||
|
"@ComponentScan CUSTOM type filter requires a TypeFilter implementation");
|
||||||
|
TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class,
|
||||||
|
environment, resourceLoader, registry);
|
||||||
|
typeFilters.add(filter);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue