Springboot源码分析之TypeFilter魔力

摘要:

在平常的开发中,不知道大家有没有想过这样一个问题,为什么我们自定义注解的时候要使用spring的原生注解(这里指的是类似@Component@Service........),要么就是 随便弄个注解,搭配自己的切面编程来实现某些业务逻辑。这篇文章主要给大家分享一下,如何脱离Spring原生注解自定义注解注入IOC

SpringBootApplication注解分析


从源代码很容易看出来,它的作用就是自动装配和扫描我们的包,并将符合的类进行注册到容器。自动装配非常简单,这里不做过多分析,接下来分析一下什么叫做符合规则的类。在@ComponentScan注解上面的过滤器类型的定义

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

    private FilterType() {
    }
}

excludeFilters排除过滤器

这个是给我们排除符合的类,不让他注册到IOC的时候使用的, Springboot默认使用两个排除过滤器,很简单的,网上随便搜都可以找到相关说明,在这儿我举个特舒列子就行了.

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;
    }
}


以上代码是正常逻辑,反过来这样想,如果将Tt类的@Component注解去掉是不是也行的,所以这种排除注解一般都用在正常可以注入到容器的时候进行添加的,那么我们上面说过,脱离Spring也可以注入到容器,该怎么实现呢?

includeFilters包含过滤器

脱离Spring原生注解,将将Tt类的@Component注解去掉

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 {
}

透过现象看本质

流程进行梳理一下,注解驱动在注入容器的关键扫描类(注意这里是指的扫描,而不是什么@Bean,@Import等其余注解都是建立在这个基础之上的)

  • 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) {
        }

    }

此处会将@Component,JSR-250 ‘javax.annotation.ManagedBean‘,JSR-330 ‘javax.inject.Named‘的注解进行注册,所以难怪我们的自定义注解必须要有这些派生注解,换一个角度来思考,它们这个地方进行类AnnotationTypeFilter的添加,我们也可以自定义AnnotationTypeFilter来将自己的定义规则的注解进行注入容器。

原文地址:https://www.cnblogs.com/qinzj/p/11516642.html

时间: 2024-10-09 06:46:57

Springboot源码分析之TypeFilter魔力的相关文章

[SpringBoot]源码分析SpringBoot的异常处理机制

微信号:GitShare微信公众号:爱折腾的稻草如有问题或建议,请在公众号留言[1] 前续 为帮助广大SpringBoot用户达到"知其然,更需知其所以然"的境界,作者将通过SpringBoot系列文章全方位对SpringBoot2.0.0.RELEASE版本深入分解剖析,让您深刻的理解其内部工作原理. 正文 在SpringBoot启动时,会查找并加载所有可用的SpringBootExceptionReporter,其源码如下: //7 使用SpringFactoriesLoader在

Springboot源码分析之番外篇

摘要: 大家都知道注解是实现了java.lang.annotation.Annotation接口,眼见为实,耳听为虚,有时候眼见也不一定是真实的. /** * The common interface extended by all annotation types. Note that an * interface that manually extends this one does <i>not</i> define * an annotation type. Also no

Springboot源码分析之EnableAspectJAutoProxy

摘要: Spring Framwork的两大核心技术就是IOC和AOP,AOP在Spring的产品线中有着大量的应用.如果说反射是你通向高级的基础,那么代理就是你站稳高级的底气.AOP的本质也就是大家所熟悉的CGLIB动态代理技术,在日常工作中想必或多或少都用过但是它背后的秘密值得我们去深思.本文主要从Spring AOP运行过程上,结合一定的源码整体上介绍Spring AOP的一个运行过程.知其然,知其所以然,才能更好的驾驭这门核心技术. @Target({ElementType.TYPE})

SpringBoot源码分析之---SpringBoot项目启动类SpringApplication浅析

源码版本说明 本文源码采用版本为SpringBoot 2.1.0BUILD,对应的SpringFramework 5.1.0.RC1 注意:本文只是从整体上梳理流程,不做具体深入分析 SpringBoot入口类 @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args

SpringBoot源码分析----(一)SpringBoot自动配置

前言 springboot项目将模块化设计发挥到及至,需要什么模块,只需导入这个模块对应的stater即可,当然,用户根据业务需要自定义相关的stater,关于自定义stater在后续章节将一一解说,学习springboot,首要了解springboot的自动配置原理,我们从springboot项目的主启动类说起逐步解读springboot自动配置的奥秘. springboot自动配置解读 @SpringBootApplication public class SpringBootQuickAp

Springboot源码分析之项目结构

摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSc

SpringBoot源码分析----(二)SpringBoot自动配置原理

自动配置原理 1.SpringBoot启动的时候加载主配置类,开启了自动配置功能  @EnableAutoConfiguration [email protected] 功能的作用 @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { 利用  AutoConfigurationImportSelector  给容器

原创001 | 搭上SpringBoot自动注入源码分析专车

前言 如果这是你第二次看到师长的文章,说明你在觊觎我的美色!O(∩_∩)O哈哈~ 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 本系列为SpringBoot深度源码专车系列,第一篇发车! 专车介绍 该趟专车是开往Spring Boot自动注入原理源码分析的专车 专车问题 Spring Boot何时注入@Autowired标注的属性? 如果注入类型的Bean存在多个Spring Boot是如何处理的? 专车示例 定义接口 public interface PersonService

【原创】005 | 搭上SpringBoot请求处理源码分析专车

前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍 该趟专车是开往Spring Boot请求处理源码分析专车,主要用来分析Spring Boot是如何将我们的请求路由到指定的控制器方法以及调用执行. 专车问题 为什么我们在控制器中添加一个方法,使用@RequestMapping注解标注,指定一个路径,就可以用来处理一个web请求? 如果多个方法的请求路径一致,Spring Boot是如何处理的? 专车示例 @RestCo