纸上得来终觉浅 绝知此事要躬行 —陆游

最近在看SpringBoot核编程思想(核心篇),看到走向注解驱动编程这章,里面有讲解到:

在SpringFramework5.0引入了一个注解@Indexed ,它可以为Spring的模式注解添加索引,以提升应用启动性能。

在往下阅读的时候,请注意一些模式注解:

Spring注解 场景说明
@Repository 数据仓库模式注解
@Component 通用组件模式注解
@Service 服务模式注解
@Controller Web控制器模式注解
@Configuration 配置类模式注解

@

使用场景

在应用中有大量使用@ComponentScan扫描的package包含的类越多的时候,Spring模式注解解析耗时就越长。

使用方法

在项目中使用的时候需要导入一个spring-context-indexer jar包,有Maven和Gradle 两种导入方式,具体可以看官网,我这里使用maven方式,引入jar配置如下:

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.1.12.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>

然后在代码中,对于使用了模式注解的类上加上@Indexed注解即可。如下:

@Indexed
@Controller
public class HelloController { }

原理说明

摘自官网:



简单说明一下:在项目中使用了@Indexed之后,编译打包的时候会在项目中自动生成META-INT/spring.components文件。

当Spring应用上下文执行ComponentScan扫描时,META-INT/spring.components将会被CandidateComponentsIndexLoader 读取并加载,转换为CandidateComponentsIndex对象,这样的话@ComponentScan不在扫描指定的package,而是读取CandidateComponentsIndex对象,从而达到提升性能的目的。

知道上面的原理,可以看一下org.springframework.context.index.CandidateComponentsIndexLoader的源码。


public class CandidateComponentsIndexLoader { /**
* The location to look for components.
* <p>Can be present in multiple JAR files.
*/
public static final String COMPONENTS_RESOURCE_LOCATION = "META-INF/spring.components"; // 省略了的代码...... @Nullable
private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) {
if (shouldIgnoreIndex) {
return null;
} try {
Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION);
if (!urls.hasMoreElements()) {
return null;
}
List<Properties> result = new ArrayList<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
result.add(properties);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + result.size() + "] index(es)");
}
int totalCount = result.stream().mapToInt(Properties::size).sum(); // 转换为CandidateComponentsIndex对象
return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
}
catch (IOException ex) {
throw new IllegalStateException("Unable to load indexes from location [" +
COMPONENTS_RESOURCE_LOCATION + "]", ex);
}
}
}

感兴趣的可以自行查看全部源码内容。

使用需注意点

虽然这个@Indexed注解能提升性能,但是在使用的时候也需要注意一一下。

假设Spring应用中存在一个包含META-INT/spring.components资源的a.jar,b.jar仅存在模式注解,那么使用@ComponentScan扫描这两个JAR中的package时,b.jar 中的模式注解不会被识别。

请务必注意这样的问题。

案例说明

使用时候存在上面的注意点,还是用一个简单的demo进行一下说明,能够更好的理解。

  • DemoA项目(使用@Indexed注解

  • DemoB项目(不使用@Indexed注解)

  • SpringBootDemo项目

    在此项目中引入DemoA.jarDemoB.jar 。然后进行如下测试,测试代码如下:

配置类,扫描模式注解

@Configuration
@ComponentScan(basePackages = "org.springboot.demo")
public class SpringIndexedConfiguration {
}

测试类:


@Test
public void testIndexedAnnotation(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringIndexedConfiguration.class); System.out.println("获取DemoA Jar中【org.springboot.demo.controller.DemoAController】");
DemoAController demoAController = context.getBean(DemoAController.class);
System.out.println("DemoAController = " + demoAController.getClass()); System.out.println("获取DemoB Jar中【org.springboot.demo.controller.DemoBController】");
DemoBController demoBController = context.getBean(DemoBController.class);
System.out.println("DemoBController = " + demoBController.getClass());
}

结果:

beanDefinitionName = demoAController
获取DemoA Jar中【org.springboot.demo.controller.DemoAController】
DemoAController = class org.springboot.demo.controller.DemoAController
获取DemoB Jar中【org.springboot.demo.controller.DemoBController】 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springboot.demo.controller.DemoBController' available

找不到 DemoBController

通过这样一个简单的Demo,验证了上面提到的使用注意点。

参考资料


欢迎关注我的公众号,技术路,一起成长。

SpringFramework5.0 @Indexed注解 简单解析的更多相关文章

  1. @Indexed 注解

    本文转载自:https://www.cnblogs.com/aflyun/p/11992101.html 最近在看 SpringBoot 核编程思想(核心篇),看到走向注解驱动编程这章,里面有讲解到: ...

  2. java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet

    一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...

  3. 对 cloudwu 简单的 cstring 进行简单解析

    题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...

  4. JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet

    一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...

  5. Android 图片加载框架Glide4.0源码完全解析(二)

    写在之前 上一篇博文写的是Android 图片加载框架Glide4.0源码完全解析(一),主要分析了Glide4.0源码中的with方法和load方法,原本打算是一起发布的,但是由于into方法复杂性 ...

  6. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  7. Maven项目pom.xml文件简单解析

    Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...

  8. 【Java基础】Java注解简单入门

    注解简单来说就是配置,是特别的配置,之前常用的配置文件,可以用注解替换.然后通过反射去获取注解的信息. 如何定义一个注解 你在IDE中新建一个注解定义,是这样的结构的: package com.nic ...

  9. 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表、Hosts_groups表、Interface表

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表.Hosts_grou ...

随机推荐

  1. Chrome 浏览器自动填表呈现淡黄色解决

      Chrome 浏览器,当记住用户名和密码后,下次填写表单时,被记住的部分会被填充为淡黄色,有些时候不好看. 解决方式如下: input:-webkit-autofill {      -webki ...

  2. java设置北京时间的时区

    java设置北京时间的时区   解决方法: 设置北京时间的时区,消除时间差. TimeZone timeZone = TimeZone.getTimeZone("GMT+8"); ...

  3. ABAP ole操作

    1.ole 如何保存和退出call method of sheetname 'saves' exporting #1 = filepath #2 = 1. call method of applica ...

  4. IntelliJ-svn配置与使用

    目录 IntelliJ-svn配置与使用 SVN的配置 版本控制主要操作按钮 版本控制相关的常用设置 Version Control窗口 @(目录) IntelliJ-svn配置与使用 SVN的配置 ...

  5. (十一)会话跟踪技术之作用域(request、session、servletContext)

    一.作用域范围 Request       保存的键值仅在下一个request对象中可以得到,作用于两个有请求关系的页面 Session        它是一个会话范围,相当于一个局部变量,从Sess ...

  6. Spring Cloud(7):事件驱动(Stream)分布式缓存(Redis)及消息队列(Kafka)

    分布式缓存(Redis)及消息队列(Kafka) 设想一种情况,服务A频繁的调用服务B的数据,但是服务B的数据更新的并不频繁. 实际上,这种情况并不少见,大多数情况,用户的操作更多的是查询.如果我们缓 ...

  7. 使用sort,uniq去重并统计出现次数

    测试文档test 1 2 3 4 1 2 1 1 sort把相同的放在一起 [root@salt-test ~]# sort test 1 1 1 1 2 2 3 4 uniq -c统计出现的次数 [ ...

  8. 金仓Kingbase数据库网页数据维护分析工具

    金仓Kingbase是优秀的国产数据库产品,在能源,政务,国防等领域广泛使用, 现在TreeSoft数据库管理系统已支持Kingbase了,直接在浏览器中就可以操作查看Kingbase数据了,十分方便 ...

  9. 三节课MINI计划第一周

    第一部分   产品经理做什么以及需要的能力 (一)用户分析 用户群——行为分析——需求痛点——产品卖点——更多用户群 (二)功能分析 产品调研——产品结构——功能点——关键流程——下一轮产品调研 (三 ...

  10. Centos7安装gitlab11 学习笔记之基础概念、部署安装、权限管理、issue管理

    一.基础介绍 1.简介 一个基于GIT的源码托管解决方案 基于rubyonrails开发 集成了nginx postgreSQL redis sidekiq等组件 2.安装要求 2g内存以上,有点占内 ...