Author’s other platforms:

| CSDN:blog.csdn.net/qq_41153943

| the nuggets: juejin. Cn/user / 651387…

| zhihu: www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

This article is about 2204 words and 10 minutes is recommended

Previous article: Spring Annotations (I) : @Configuration, @Bean to register components in a container, explained how simple component registration can be done using Configuration files and annotations. Here’s how to use the @ComponentScan annotation to automatically scan components.

Building on the previous code, if you use a configuration file for component scanning, you need to use the context: Component-scan tag element in the configuration file, beans.xml:

<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd "> <! -- Packet scanning, Any component annotated with any of the four @controller@service@repository @component annotations will be scanned and loaded into the container --> <context:component-scan base-package="com.xinyi"></context:component-scan> <bean id="Person" class="com.xinyi.bean.Person"> <property </property> <property name="age" value="18"></property> </bean> </beans>Copy the code

If you annotate component scanning, you need to add a @ComponentScan component to the configuration class:

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.xinyi.bean.Person; // @configuration is equivalent to telling Spring that this is a Configuration class @configuration //value specifies the package to scan, @componentScan (value="com.xinyi") public class MyConfig {@componentScan (value="com.xinyi") @bean ("person222") public person Person111 () {return new person ("xinyi, ",19); }}Copy the code

Create a new Controller, service, and DAO:

package com.xinyi.controller; import org.springframework.stereotype.Controller; // The class marked by @Controller is actually a Controller object. The distribution // handler scans the methods of the class that uses the annotation and checks if the method uses the @requestMapping annotation. //@Controller just defines a Controller class, and the @requestMapping method is the handler that handles the request. @Controller public class MyController { }Copy the code
package com.xinyi.service; import org.springframework.stereotype.Service; @service public class MyService {}Copy the code
package com.xinyi.dao; import org.springframework.stereotype.Repository; @repository public class MyDao {} @repository public class MyDao {}Copy the code

Create a new test class and output the scanned components:

package com.xinyi.test; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.xinyi.config.MyConfig; public class Test { @Test public void test1() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); String[] strings = applicationContext.getBeanDefinitionNames(); for(String string : strings) { System.out.println(string); }}}Copy the code

The output components are:

myConfig
myController
myDao
myService
person222
Copy the code

In addition, the includeFilters and ExcludeFilters properties of the @ComponentScan annotation specify which components to scan and exclude which components to not scan. The includeFilters and ExcludeFilters properties accept arrays of parameters.

/**
   * Specifies which types are eligible for component scanning.
   * <p>Further narrows the set of candidate components from everything in {@link #basePackages}
   * to everything in the base packages that matches the given filter or filters.
   * <p>Note that these filters will be applied in addition to the default filters, if specified.
   * Any type under the specified base packages which matches a given filter will be included,
   * even if it does not match the default filters (i.e. is not annotated with {@code @Component}).
   * @see #resourcePattern()
   * @see #useDefaultFilters()
   */
  Filter[] includeFilters() default {};
  /**
   * Specifies which types are not eligible for component scanning.
   * @see #resourcePattern
   */
  Filter[] excludeFilters() default {};
Copy the code

ExcludeFilters specify components that are not scanned:

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import com.xinyi.bean.Person; / / excludeFilters: Service and Repository @componentScan (value="com.xinyi",excludeFilters = {@Filter(type=FilterType.ANNOTATION,classes = {Service.class,Repository.class})}) public class MyConfig { // @bean injects a Bean into the container of type return value type, @bean ("person222") public person Person111 () {return new person ("xinyi, ",19); }}Copy the code

Output results:

// Dao and service myConfig myController Person222 are excludedCopy the code

The IncludeFilters attribute has a useDefaultFilters parameter. The default value is true, which means that all packets are scanned by default. Therefore, if you add a filter rule to scan the specified component, UseDefaultFilters =false:

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import com.xinyi.bean.Person; @ComponentScan(value="com.xinyi",includeFilters = {@Filter(type=FilterType.ANNOTATION,classes = {Service class, Repository. Class})}, useDefaultFilters = false) public class MyConfig {/ / @ Bean to inject a Bean container, type is the type of return value, @bean ("person222") public person Person111 () {return new person ("xinyi, ",19); }}Copy the code

The output components are:

// Controller myConfig myDao myService Person222 is not scannedCopy the code

FilterType is an enumerated class that defines various filtering types:

public enum FilterType { /** * Filter candidates marked with a given annotation. * @see . Org. Springframework. Core type. The filter. AnnotationTypeFilter * / / / the ANNOTATION in the annotations of way /** * Filter candidates assignable to a given type. * @see org.springframework.core.type.filter.AssignableTypeFilter */ // Given the type ASSIGNABLE_TYPE, /** * Filter candidates matching a given AspectJ type pattern expression. * @see . Org. Springframework. Core type. The filter. AspectJTypeFilter * / / / in accordance with the ASPECTJ expression ASPECTJ, /** * Filter candidates matching a given regex pattern. * @see . Org. Springframework. Core type. The filter. RegexPatternTypeFilter * / / / in accordance with the regular expression REGEX, /** Filter candidates using a given custom * {@link org.springframework.core.type.filter.TypeFilter} implementation. */ // Follow CUSTOM rules CUSTOM}Copy the code

The above filtering types are used in the same way as annotation types. Most filtering types are based on the specified type and custom rules, for example:

1. Filter according to the specified type:

@ComponentScan(value="com.xinyi",includeFilters = {@Filter(type=FilterType.ASSIGNABLE_TYPE,classes = {MyDao.class})},useDefaultFilters = false)
Copy the code

2. Filter according to user-defined rules:

First, create a custom filter rule:

package com.xinyi.config; import java.io.IOException; import org.springframework.context.annotation.AnnotationBeanNameGenerator; 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 MyTypeFilter implements TypeFilter {//metadataReader: implements the currently scanned class MetadataReaderFactory: reads information from any other class. // The match method returns a Boolean value. True indicates a match. Public Boolean match(MetadataReader, MetadataReader, MetadataReaderFactory MetadataReaderFactory) throws IOException {// TODO auto-generated method stub // Obtains information about the current class annotation AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); / / for scanning for the class information ClassMetadata ClassMetadata = metadataReader. GetClassMetadata (); / / get the current class Resource information (information) Resource Resource. = metadataReader getResource (); String classnameString = classMetadata.getClassName(); System.out.println(" Scanning class: "+classnameString); if(classnameString.contains("er")) { return true; } return false; }}Copy the code

Using custom filtering rules:

@ComponentScan(value="com.xinyi",includeFilters = {@Filter(type=FilterType.CUSTOM,classes = {MyTypeFilter.class})},useDefaultFilters = false)
Copy the code

Output result:

@ComponentScan annotation, equal to multiple @ComponentScan annotation (in a class can write multiple @ComponentScan annotation, define a variety of packet scanning filtering rules), so if you define a variety of component scanning filtering rules, You can annotate this with @ComponentScans:

@ComponentScans(value = {
@ComponentScan(value="com.xinyi",includeFilters = {@Filter(type=FilterType.ANNOTATION,classes = {Service.class,Repository.class})},useDefaultFilters = false),... })
Copy the code

That’s how you use the @ComponentScan annotation for packet scanning in annotation development and define packet scanning filtering rules using IncludeFilters and ExcludeFilters properties.

Finally, welcome to pay attention to the public number: 1024 notes, free access to massive learning resources (including video, source code, documents)!

Related recommendations:

  • Spring annotation (3) : @scope sets the scope of the component

  • Spring is worth your collection!!

  • Spring annotation (7) : Assign attributes to beans using @value

  • SpringBoot develops Restful interfaces to implement CRUD functions

  • Introduction to distributed cache middleware Redis