springboot自动装配中的SPI机制

springboot的自动装配

SpringBootApplication 本质上是由 3 个注解组成,分别是
1. @Configuration
2. @EnableAutoConfiguration
3. @ComponentScan

@Configuration是 JavaConfig形式的基于 Spring IOC 容器的配置类使用的一种注解。

@ComponentScan 这个注解是大家接触得最多的了,相当于 xml 配置文件中的<context:component-scan>。 它的主要作用就是扫描指定路径下的标识了需要装配的类,自动装配到 spring 的 Ioc 容器中。

@EnableAutoConfiguration为了实现自动装配

@EnableAutoConfiguration

本质上来说,其实 EnableAutoConfiguration 会帮助springboot 应用把所有符合@Configuration 配置都加载到当前 SpringBoot 创建的 IoC 容器,而这里面借助了Spring 框架提供的一个工具类 SpringFactoriesLoader 的支持。以及用到了 Spring 提供的条件注解@Conditional,选择性的针对需要加载的 bean 进行条件过滤

@Import(AutoConfigurationImportSelector.class)将第三方提供的 bean 的配置类AutoConfigurationImportSelector导入IOC。

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
				annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

通过上面源码的一步步深入可以定位到

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());

SpringFactoriesLoader这个工具类和JDK的SPI原理一样,不过它比 SPI 更好的点在于不会一次性加载所有的类,而是根据 key 进行加载。

SpringFactoriesLoader 的 作 用 是 从classpath/META-INF/spring.factories 文件中,根据 key 来加载对应的类到 spring IoC 容器中。

先扫描 spring-autoconfiguration-metadata.properties文件,最后在扫描 spring.factories 对应的类时,会结合前面的元数据进行过滤,过滤的原因是很多的@Configuration 其实是依托于其他的框架来加载的,如果当前的 classpath 环境下没有相关联的依赖,则意味着这些类没必要进行加载,所以,通过这种条件过滤可以有效的减少@configuration 类的数量从而降低SpringBoot 的启动时间。

自动装配的Demo

git地址:https://gitee.com/pengzhang_master/spring-boot-enableauto

项目结构

core-test模块

package core;

public class Core {

    public String study(){
        System.out.println("good good study, day day up");
        return "hhhhhhhh";
    }
}
package core;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Bean
    public Core Core(){
        return new Core();
    }
}

spring.factories下添加自动装配的类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=core.Config

enableauto模块

此模块是springboot项目

package com.example.enableauto;

import core.Core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class EnableautoApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext run = SpringApplication.run(EnableautoApplication.class, args);
		System.out.println(run.getBean(Core.class).study());
	}

}

测试

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 的自动装配机制是其核心特性之一,它能够根据项目的依赖和配置,自动加载和配置需要的组件和功能。这使得开发者可以更加专注于业务逻辑的实现,而无需手动配置大量的代码。 Spring Boot 的自动装配机制基于条件注解(@Conditional),它根据一些条件判断是否需要装配某个组件或功能。这些条件可以是类路径上的依赖、配置属性的值、Bean 的存在与否等等。 自动装配可以通过以下几种方式实现: 1. 自动配置:Spring Boot 提供了大量的自动配置类,这些类根据条件注解自动配置了一些常用的组件和功能,例如数据库连接池、Web 容器等。开发者只需添加相应的依赖,Spring Boot 就能自动根据条件进行配置。 2. 条件注解:开发者可以使用条件注解来控制某个组件或功能是否被装配。例如,使用@ConditionalOnClass注解可以在类路径上存在某个类时才进行装配,@ConditionalOnProperty注解可以根据配置属性的值进行条件装配等等。 3. 自定义装配:除了使用Spring Boot提供的自动配置外,开发者还可以自定义装配。通过编写自己的条件注解和自动配置类,可以实现对特定组件或功能的自动装配。 总之,Spring Boot 的自动装配机制大大简化了开发过程,减少了繁琐的配置工作,提高了开发效率。开发者只需关注业务逻辑的实现,而不需要过多地关心底层的配置和组件装配

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值