SpringFramework5.0 @Indexed注解 简单解析

纸上得来终觉浅 绝知此事要躬行 —陆游最近在看SpringBoot核编程思想(核心篇),看到走向注解驱动编程这章,里面有讲解到:在SpringFramework5.0引入了一个注解@Indexed ,它可以为Spring的模式注解添加索引,以提升应用启动性能。官网地址:Spring Framework 5.1.12.RELEASE beans-scanning-index…

大家好,又见面了,我是全栈君。

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

最近在看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,验证了上面提到的使用注意点。

参考资料


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

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120987.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm加注释的快捷方式_pycharm全部注释

    pycharm加注释的快捷方式_pycharm全部注释Ctrl+F1显示错误描述或警告信息Alt+Enter快速修正Ctrl+R替换Ctrl+Shift+F或者连续2次敲击shift全局查找{可以在整个项目中查找某个字符串什么的,如查找某个函数名字符串看之前是怎么使用这个函数的}Ctrl+Shift+R全局替换Alt+Shift+F10运行模式配置Alt+…

    2022年8月28日
    6
  • C#发送邮件C/s,B/s通用

    C#发送邮件C/s,B/s通用

    2021年7月31日
    54
  • IDEA的优化配置

    IDEA的优化配置前言IDEA全称IntelliJIDEA,是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、创新的GUI设计等方面的功能可以说是超常的。idea的优化可以使我们更得心应手的高效开发设置优化方法分割线一个文件可能会有一个或多个方法,堆积在一起使人眼花缭乱。方法分割线可以是我们快速区分方法。File——Setting——Edi

    2022年5月21日
    49
  • 一文搞懂反卷积,转置卷积

    一文搞懂反卷积,转置卷积一文搞懂反卷积,转置卷积前言本文翻译自《Up-samplingwithTransposedConvolution》,这篇文章对转置卷积和反卷积有着很好的解释,这里将其翻译为中文,以飨国人。如有谬误,请联系指正。转载请注明出处。联系方式:e-mail:FesianXu@163.comQQ:973926198github:https://github.com…

    2022年6月21日
    28
  • dispatch_once认识分析

    dispatch_once认识分析

    2022年1月5日
    45
  • linux密码记录木马,注意 “QQ大盗”木马注入 QQ 进程记录QQ账号与密码[通俗易懂]

    linux密码记录木马,注意 “QQ大盗”木马注入 QQ 进程记录QQ账号与密码[通俗易懂]“QQ大盗”变种AC(Win32.PSWTroj.QQPass.ac)是一个盗取QQ账号和密码的木马病毒。“网游追击者”变种CD(Win32.Troj.LipGame.cd)是一个盗取多个网络游戏账号的木马病毒。一、“QQ大盗”变种AC(Win32.PSWTroj.QQPass.ac)威胁级别:★该病毒是一个盗号木马,它会潜伏在受感染的电脑系统里,监视并伺机注入到QQ进程里,创建信息勾子,记录用…

    2022年7月20日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号