SpringBoot系列—@SpringBootApplication源码解析(三)

个人博客:haichenyi.com。感谢关注

  上一篇,内容很少,说了一下SpringBoot的底层是怎么依赖的。这一篇讲一下SpringBoot底层源码是怎么实现的。

  从SpringBoot的入口开始。第一篇的时候说过了,最好把入口文件放在最外层的包下面,至于原因就不多阐述了。

  说说这个 @SpringBootApplication注解的原理,点进去看一下:

如下图:

springbootapplication注解.png

主要就是这三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

@SpringBootConfiguration

  SpringBootConfiguration这个注解是由Configuration注解实现的。

@Configuration

  从名字上就可以判断出,这个注解是跟SpringBoot配置相关的,@Configuration,这个注解是Spring底层的一个注解,之前都是配置xml,SpringBoot推荐我们用配置类来描述配置,配置类是什么呢?就用@Configuration标记的类。

  Configuration这个注解是由Component注解实现。

@Component

  这个注解的意义就是,把当前的配置类添加到spring容器中,表示是一个组件。

@EnableAutoConfiguration

  EnableAutoConfiguration这个注解是由AutoConfigurationPackage和**@Import({AutoConfigurationImportSelector.class})**注解实现

@AutoConfigurationPackage

  这个注解从名字上面看出来是自动配置包,这是什么意思呢?在第一篇我们就说过了入口要放在最外层的包,至于原因,已经讲过了,因为SpringBoot会自动将引导类 @SpringBootApplication标注的类所在的包以及下面所有子包里面所有的组件扫描到Spring容器中统一管理。就是这个注解实现的。那么,这个注解是怎么实现的呢?就是通过它的这个 @Import({Registrar.class}),下面就是Registrar类的源码了

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
        }

        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
        }
    }

  就是通过下面这个代码注册进去的。

AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
@Import({AutoConfigurationImportSelector.class})

  这个注解是干什么用的呢?

  1. 它会把项目里面所有需要导入的组件以全类名的方式返回,将这些组件添加到容器中。
  2. 会给容器中注入非常多的自动配置类,就是导入并配置好当前项目中
    所需要的组件,省去我们手动编写配置去注入组件。

  怎么实现的呢?打开AutoConfigurationImportSelector类,找到如下代码:

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

找到getCandidateConfigurations方法,如下:

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
    }

找到loadFactoryNames方法,如下:

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
    }

找到loadSpringFactories方法,里面有

Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");

这里就是我们的配置,我们这个配置具体是在哪呢?如下图

autoConfigure.png

@ComponentScan

  这个注解的主要作用就是,被该注解标识的类会被Spring容器纳入管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海晨忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值