springboot学习(十六):了解springboot自动装配kafka原理

本文通过源码分析,详细介绍了SpringBoot如何自动装配Kafka,从创建SpringApplication开始,逐步揭示@EnableAutoConfiguration的工作机制,特别是AutoConfigurationImportSelector的selectImports方法,最后展示了KafkaAutoConfiguration如何创建相关bean。
摘要由CSDN通过智能技术生成

说明

在上篇《springboot学习(十五):Kafka的使用》博文中,通过简单的示例介绍了如何在springboot项目中使用kafka。代码十分简单,通过配置文件和注解就可以操作kakfa集群。本篇博文将通过springboot的源码来了解springboot如何自动装配kafka。

创建SpringApplication

从程序启动入口入手阅读代码:


@SpringBootApplication
public class Kafka2Application {

	public static void main(String[] args) {
		SpringApplication.run(Kafka2Application.class, args);
	}
}

在以上代码中,使用了@SpringBootApplication注解,在main方法中调用了SpringApplication的run方法。

@SpringBootApplication注解是一个组合注解:
它主要包含了@SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan等注解,通过这三个注解实现了bean的配置和加载。

其中@EnableAutoConfiguration注解中通过@import引入了AutoConfigurationImportSelector类,该类对springboot的自动装配十分重要。

@ComponentScan注解通过扫描包中的@Bean注解来实现bean加载,当没有指定包的位置时,会默认扫描该注解所在包,所以启动类被放置在“最外面”

在调用SpringApplication的run方法时,将启动类作为参数,创建SpringApplication对象

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class[]{primarySource}, args);
}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return (new SpringApplication(primarySources)).run(args);
}

在创建SpringApplication对象的方法中,通过判断classpath中类的类型来设置WebApplication的类型,并设置项目初始化器和监听器。

this.webApplicationType = WebApplicationType.deduceFromClasspath();  // 设置WebApplication的类型
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 设置初始化器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); // 设置监听器

在设置初始化器和监听器时,都调用了getSpringFactoriesInstances方法,并设置了不同类类对象做为参数,而在该改方法中使用了SpringFactoriesLoader的loadFactoryNames方法,获取META-INF/spring.factories文件中配置的对应类的全限定名。

在springboot2.0版本中对loadFactoryNames方法做了改进,一次加载spring.factories文件中的所有内容并缓存起来。在之前的版本中会不断重复加载,只获取当前需要的内容。

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
        return result;
    } else {
        try {
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();

            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryClassName = ((String)entry.getKey()).trim();
                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    int var10 = var9.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        String factoryName = var9[var11];
                        result.add(factoryClassName, factoryName.trim());
        
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值