Spring study notes (b) --- Notes @ComponentScan

1. Source resolve

@ComponentScan from the translation we can know that it is a component of the scanner, this scanner where we can scan a specified range, the corresponding filter systems are specified for our settings, you can even use our custom filters.
[1] Here we start with the source code in several major ways talk

public @interface ComponentScan {
	//这个value值就是指定我们扫描包的路径
	//@AliasFor这里指的是使用时可以使用的另一个别名
	@AliasFor("basePackages")
	String[] value() default {};
	//指定包含类型的过滤器,在这里面可以指定Filter来设定我们过滤时通过什么辨别(最常用的是注解和类)
	Filter[] includeFilters() default {};
	//指定需要排除类型的过滤器
	Filter[] excludeFilters() default {};
	@Target({})
	@interface Filter {
		//Filter的类型(默认是注解)
		FilterType type() default FilterType.ANNOTATION;
		@AliasFor("classes")
		Class<?>[] value() default {};		
		@AliasFor("value")
		Class<?>[] classes() default {};
		String[] pattern() default {};

[2] FilterType this class shows that we can fill in values


package org.springframework.context.annotation;

public enum FilterType {

	/**
	 * Filter candidates marked with a given annotation.
	 * @see org.springframework.core.type.filter.AnnotationTypeFilter
	 * 指定的注解(使用较多)
	 */
	ANNOTATION,
	/**
	 * Filter candidates assignable to a given type.
	 * @see 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.
	 * 自定义类型(使用较多)
	 */
	CUSTOM

}

[3] look ignorant force, are you talking about? We illustrate it with an example includeFilters

@Configuration
//@Controller  @Service @Respostry @Component
@ComponentScan(value="com.enjoy.cap2", 
	includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}
	,useDefaultFilters=false)
public class Cap2MainConfig {

Analysis: This annotation at the class, which indicate the need to scan the value of the package (com.enjoy.cap2 This is my new package, which has @Controller @Service @Respostry @Component these notes indicated category) ; Next includeFilters designate corresponding component rules, such as (i.e., our corresponding annotations comprises scanning) by FilterType.ANNOTATION, the latter used to represent classes corresponding annotation class (Controller-based), and we finally to scan on the only the standard @Controller class, and the rest of the class was filtered out.
useDefaultFilters = false and this is what ah, we take it into the source code again

/**
  * Indicates whether automatic detection of classes annotated with {@code @Component}
 * {@code @Repository}, {@code @Service}, or {@code @Controller} should be enabled.
 * 指示是否自动检测用{@code@Component}注释的类应该启用{@code@Repository}、{@code@Service}或{@code@Controller}。
**/
boolean useDefaultFilters() default true;

By default it is open, that is, we do not set the appropriate set of filter rules, it will continue to scan these packages annotated classes. This is the reason we set it to false, because we now only need it to scan the corresponding class @Controller it. (If this is true, we set filtering rules will fail)

Next we use excludeFilters to illustrate the difference between it and above

@Configuration
//@Controller  @Service @Respostry @Component
@ComponentScan(value="com.enjoy.cap2", 
	excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}
	,useDefaultFilters=false)
public class Cap2MainConfig {

Some people will take for granted, not that the includeFilters changed excludeFilters be able to achieve the appropriate exclusions you, this has nothing to say. Yes, you're right, but it should be noted that useDefaultFilters = false this is not possible, because we closed its scan, then how do we exclude all the same no effect, because we simply do not perform on the corresponding comments the appropriate scan, then we need to turn scan, that is above useDefaultFilters = true can be changed to normal use.
[4] From the above we already know the relevant attributes includeFilter and excludeFilter, then we we will look further into the correlation values of these two attributes @Fiter can be used.

2. Filter class definitions from @Filter

We have already learned that there FilterType type ANNOTATION (default), ASSIGNABLE_TYPE (we need to scan the specified class, such as xxxController.class); in addition to the two most commonly used is beyond our CUSTOM (custom type), you can this type of filter to set our own rules
FilterType this class three most commonly used values


package org.springframework.context.annotation;

public enum FilterType {
	ANNOTATION,
	ASSIGNABLE_TYPE,
	CUSTOM
}

[1] write a custom filter class (where you can write our own filtering rules)
MyTypeFilter this class needs to inherit TypeFilter

package com.enjoy.cap2.config;

import java.io.IOException;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

public class JamesTypeFilter implements TypeFilter {

	/**
	 * MetadataReader: 读取当前正在扫描类的信息
	 * MetadataReaderFactory: 可以获取到其他类的信息
	 */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		/**这里只是说明它拥有方法**/
		//获取当前类注解的信息
		//AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//获取当前的资源(类的路径)
		//Resource resource = metadataReader.getResource();
		
		//获取正在扫描的类信息
		ClassMetadata classMetadata = metadataReader.getClassMetadata();

		String className = classMetadata.getClassName();
		System.out.println("----->"+className);
		/**
		  获取我们扫描的包中的类名,如果我们只需要得到相应的订单类Order,这时候我们就
		  可以设置它的匹配规则如下
		**/
		if(className.contains("Order")) { 
			//当类包含Order字符,则匹配成功,返回true
			return true;
		}
		return false;
	}

}

[2] into our custom filtering rules in the main configuration class
FilterType to be used herein FilterType.CUSTOM, which is our custom type. classes is our class name. After this introduction we can make the appropriate filter according to the rules you define (such as Order here only relevant when our class will match the rule to the corresponding scan)

@Configuration
//@Controller  @Service @Respostry @Component
@ComponentScan(value="com.enjoy.cap2",includeFilters= {
		@Filter(type= FilterType.CUSTOM,classes= {MyTypeFilter.class})
	}
	,useDefaultFilters=false)
public class Cap2MainConfig {

summary

@ComponentScan(value=“com.enjoy.cap2”,includeFilters= {
@Filter(type= FilterType.CUSTOM,classes= {MyTypeFilter.class})
}
,useDefaultFilters=false)

This covering the above stated, as long as we know the path corresponding packet @ComponentScan value specified by the scanning, and through
to the table or command satisfies the condition includeFilters excludeFilters containing it or exclude it, and the condition is by FilterType on @Filte to specify annotations, class, custom class and so on.

Published 70 original articles · won praise 2 · Views 5485

Guess you like

Origin blog.csdn.net/TheWindOfSon/article/details/105055389