TypeFilter magic Springboot source code analysis of the

Summary:

In normal development, do not know if you have not thought about such a problem, why do we custom annotation when you want to use native Notes spring of (in this case is similar @Component, @Service........), or is just get hold of the notes, with their cut programming to achieve certain business logic. This article to share with you, and how to escape Spring原生注解custom annotation injectionIOC

SpringBootApplication analysis notes

file
From the source code is easy to see, it is the role of automatic assembly and scan our package and conforming to the container type to be registered. Automatic assembly is very simple, do not do too much analysis here, then analyze what is called 符合规则的类. In the @ComponentScanfilter of the type defined above annotations

public enum FilterType {
    ANNOTATION, //注解类型
    ASSIGNABLE_TYPE, //指定的类型
    ASPECTJ, //按照Aspectj的表达式,基本上不会用到
    REGEX, //按照正则表达式
    CUSTOM; //自定义

    private FilterType() {
    }
}

Exclusion filters excludeFilters

This class is for us to exclude matching, let him registered to IOCthe use of the time, Springboot use two filters to exclude default, a very simple, casual search online you can find instructions, here I give Teshu Liezi on the line a.

package com.github.dqqzj.springboot.filter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author qinzhongjian
 * @date created in 2019-07-30 19:14
 * @description: TODO
 * @since JDK 1.8.0_212-b10
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dqqzj {
    String value();
}
package com.github.dqqzj.springboot.filter;

import org.springframework.stereotype.Component;

/**
 * @author qinzhongjian
 * @date created in 2019-07-29 22:30
 * @description: TODO
 * @since JDK 1.8.0_212-b10
 */
@Dqqzj(value = "dqqzj")
@Component
public class Tt {
}
package com.github.dqqzj.springboot.filter;

import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

/**
 * @author qinzhongjian
 * @date created in 2019-07-30 19:13
 * @description: TODO
 * @since JDK 1.8.0_212-b10
 */
public class MyTypeFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        if (metadataReader.getAnnotationMetadata().isAnnotated(Dqqzj.class.getName())) {
            return true;
        }
        return false;
    }
}

file
The above code is normal logic, in turn, I thought that if the Ttclass @Componentnotes are not also remove the line, so this exclusion notes are generally used in normal can be injected into the container when to add, and then we said above, from the SpringIt can also be injected into the container, how to achieve it?

includeFilters filter comprising

From Spring原生注解the the Ttclass @Componentannotation removed

package com.github.dqqzj.springboot.filter;

import org.springframework.stereotype.Component;

/**
 * @author qinzhongjian
 * @date created in 2019-07-29 22:30
 * @description: TODO
 * @since JDK 1.8.0_212-b10
 */
@Dqqzj(value = "dqqzj")
//@Component
public class Tt {
}

file

Look beyond the surface

Processes comb, annotation-driven injection at a critical scanning type container (note that this is referring to the scan, rather than what @ Bean, @ Import and other remaining notes are built on the basis of)

  • ComponentScanAnnotationParser
  • ClassPathBeanDefinitionScanner
  • ClassPathScanningCandidateComponentProvider
ClassPathScanningCandidateComponentProvider#registerDefaultFilters
protected void registerDefaultFilters() {
        this.includeFilters.add(new AnnotationTypeFilter(Component.class));
        ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();

        try {
            this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
            this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
        } catch (ClassNotFoundException var4) {
        }

        try {
            this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
            this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
        } catch (ClassNotFoundException var3) {
        }

    }

Here will be @Component, JSR-250 'javax.annotation.ManagedBean', JSR-330 'javax.inject.Named'annotations register, so no wonder our custom annotation must have derived these notes, from a different angle to think that this place be like AnnotationTypeFilterto add, we can also customize AnnotationTypeFilterto your own definition of the rules the notes were injected into the container.

Guess you like

Origin www.cnblogs.com/qinzj/p/11516642.html