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来将自己的定义规则的注解进行注入容器。
Springboot源码分析之TypeFilter魔力的更多相关文章
- SpringBoot源码分析之SpringBoot的启动过程
SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30 | 分类于 springboot | 0 Comments | 阅读次数 SpringB ...
- Springboot源码分析之项目结构
Springboot源码分析之项目结构 摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 4. ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
- springboot源码分析-SpringApplication
SpringApplication SpringApplication类提供了一种方便的方法来引导从main()方法启动的Spring应用程序 SpringBoot 包扫描注解源码分析 @Spring ...
- Springboot源码分析之jar探秘
摘要: 利用IDEA等工具打包会出现springboot-0.0.1-SNAPSHOT.jar,springboot-0.0.1-SNAPSHOT.jar.original,前面说过它们之间的关系了, ...
- Springboot源码分析之代理三板斧
摘要: 在Spring的版本变迁过程中,注解发生了很多的变化,然而代理的设计也发生了微妙的变化,从Spring1.x的ProxyFactoryBean的硬编码岛Spring2.x的Aspectj注解, ...
- Springboot源码分析之事务拦截和管理
摘要: 在springboot的自动装配事务里面,InfrastructureAdvisorAutoProxyCreator ,TransactionInterceptor,PlatformTrans ...
- SpringBoot源码分析(二)启动原理
Springboot的jar启动方式,是通过IOC容器启动 带动了Web容器的启动 而Springboot的war启动方式,是通过Web容器(如Tomcat)的启动 带动了IOC容器相关的启动 一.不 ...
- Springboot源码分析之Spring循环依赖揭秘
摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...
随机推荐
- python3学习-lxml模块
在爬虫的学习中,我们爬取网页信息之后就是对信息项匹配,这个时候一般是使用正则.但是在使用中发现正则写的不好的时候不能精确匹配(这其实是自己的问题!)所以就找啊找.想到了可以通过标签来进行精确匹配岂不是 ...
- C++基础之:扫雷破解
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- 【CodeForces - 1200A】Hotelier(水题、模拟)
Hotelier 直接翻译了 Descriptions Amugae的酒店由10人组成10客房.房间从0开始编号0到99 从左到右. 酒店有两个入口 - 一个来自左端,另一个来自右端.当顾客通过左入口 ...
- 5 X 5 方阵引出的寻路算法 之 路径遍历(完结)
此篇文章源自对一个有趣问题的思考,在我的另一篇博文<一个有趣的 5 X 5 方阵一笔画问题>中有详细介绍.在已知其结论的情况下,作为程序员的我,还是想利用该问题当做出发点,写一个可以遍 ...
- 微信小程序项目总结-记账小程序(包括后端)
一.小程序部分 这是理财系统的前端,江苏海洋大学微信小程序比赛,最后获得了一等奖 GitHub:https://github.com/GeorgeLeoo/finance 1. 项目描述 (1). 此 ...
- nessus安装
1.安装注册 (1)从https://www.tenable.com/products/nessus/select-your-operating-system上下载对应操作系统版本的nessus,结果 ...
- GLFW+GLAD OpenGL Mac开发环境搭建
前言 OpenGL 是什么?The Industry Standard for High Performance Graphics 这是官方解释.说白了他就是一套标准接口.对,是接口,并没有实现具体的 ...
- Springboot源码分析之AbstractAdvisorAutoProxyCreator
摘要: Spring的代理在上层中主要分为ProxyCreatorSupport和ProxyProcessorSupport,前者是基于代理工厂,后者是基于后置处理器,也可以认为后置就是自动代理器.当 ...
- java IO流 之 FIle类基础
package IO; import java.io.File;import java.io.IOException; public class FileIO { /** * 构建及获取文件名信息 * ...
- JMeter用户参数
压测的时候,经常需要使用动态参数,即每次请求的参数不一样,这样才能更好的模拟真实的用户请求,我们首先能想到的也是最常见的就是用户ID 1. 用户参数 我们可以定义一个变量,然后指定多个值,这样每次请 ...