Spring annotation version -- automatic scanning and filtering rules

During the development of spring annotation version, we usually establish a Configuration class of our own. The so-called Configuration class is to add @ Configuration annotation on the class. If the default filter rule is used, mark @ Controller,@Service,@Repository,@Component on the class,
The Spring container scans and reads the annotation Bean definition class according to the annotation filtering rules, and registers it into the Spring IoC container.

@ComponentScan is the component scanning of spring. Go to its source code to see. This is the general notes

	@AliasFor("basePackages")
	String[] value() default {};

	/**
	 * Base packages to scan for annotated components.
	 * <p>{@link #value} is an alias for (and mutually exclusive with) this
	 * attribute.
	 * <p>Use {@link #basePackageClasses} for a type-safe alternative to
	 * String-based package names.
	 */
	@AliasFor("value")
	String[] basePackages() default {};

Here, value and basePackages become aliases for each other. Generally speaking, they are the same.
@ComponentScan(value = "xxx") and @ ComponentScan(basePackages = "xxx") are consistent.
Our concern

boolean useDefaultFilters() default true;

Use the default filter, that is, all the above annotations will be loaded into the IOC container (note that @ Conditional annotation needs to meet the conditions). If it is off, it will only load the primary key according to the set filter rules, and the above annotations will be loaded (the beans in the class will also be loaded by default, because @ bean is an example by default, initialized in the IOC container It will be loaded. If @ Scope ("prototype") you set is not loaded, it will only be loaded when it is called.

1. If the default loading verification is used and the above annotations are added, all will be loaded

2. Turn off default loading, only running annotations will be loaded

You can see that all User related and other config (no content, just a demonstration, not all @ Configuration will be loaded) have not been loaded. It resolves that the default loading condition is all.

Filter[] includeFilters() default {};
//Contain
Filter[] excludeFilters() default {};
//Exclude, do not include

Their usage is similar. Let's take excludeFilters as an example:

It is a Filter [], that is, the Filter array. Enter filer

@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {
		//Filter type, default by annotation
		FilterType type() default FilterType.ANNOTATION;
			
		@AliasFor("classes")
		Class<?>[] value() default {};//Class, alias should not be forgotten
		
		@AliasFor("value")
		Class<?>[] classes() default {};//class
		
		String[] pattern() default {};//Regular filtering
	}

Continue to FileterType, which is an enumeration class:

public enum FilterType {
	ANNOTATION,
	ASSIGNABLE_TYPE,
	ASPECTJ,
	REGEX,
	CUSTOM
}

Read it:
FilterType.ANNOTATION: by annotation, default
Filtertype.assignable'type: by given type
FilterType.ASPECTJ: use ASPECTJ
FilterType.REGEX: using regular expressions
FilterType.CUSTOM: use custom rules

Demonstration:

**FilterType.ANNOTATION: by annotation, default**
We found that UserController is not in the container


2. Filtertype. Designable_type: by given type
The UserService is gone

FilterType.ASPECTJ: use ASPECTJ
FilterType.REGEX: using regular expressions
These two don't work

package com.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 MyFilter implements TypeFilter{

	/**
	 * metadataReader:Read the information of the currently scanning class 
	 * metadataReaderFactory: You can get any other class information
	 */
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		// Get current class annotation information(Current class index componentScan Specify the scanned class,)
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		// Get the class information of the class currently being scanned
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		// Get the resources of the current class(Class path)
		Resource resource = metadataReader.getResource();
		// Get class name
		String className = classMetadata.getClassName();
		// Test, return true if the class name contains "Dao"
		if (className.contains("Dao")) {
			return true;
		}
		return false;

	}
}


@Configuration
@ComponentScan(value="com",excludeFilters= {
		@Filter(type=FilterType.CUSTOM,value= {MyFilter.class})//custom
})

You don't need to turn off customization, because what I use is not included. If I turn off, I can only load and run to IOC

UserDao is filtered

**@ComponentScans() * * it's an array
You can put multiple @ ComponentScan()

@ComponentScans(value= {
		@ComponentScan(value="com",excludeFilters= {
				@Filter(type=FilterType.CUSTOM,value= {MyFilter.class})//custom
		})	
})

Just like the above configuration.

Published 22 original articles, won praise 6, visited 520
Private letter follow

Tags: Spring Attribute Java

Posted on Sun, 09 Feb 2020 02:31:33 -0800 by redmonkey