zoukankan      html  css  js  c++  java
  • @SpringBootApplication你知多少?

    我们都知道@SpringBootApplication注解是spring boot项目的启动注解。那么它具体表示什么含义呢,或者说都包含什么功能呢?接下来我们一探究竟。

    一、解析@SpringBootApplication

    SpringBootApplication是一个组合注解

    1598407219679

    1598407238400

    (1)元注解

    前四个是专门用于对注解进行注解的,称为元注解。

    • @Target
    • @Retention
    • @Documented
    • @Inherited:表示该注解会被子类自动继承。

    (2)@SpringBootConfiguration

    查看该注解的源码注解可知,该注解与@Configuration 注解功能相同,仅表示当前类为一个 JavaConfig 类,其就是为 Spring Boot 专门创建的一个注解。 所以,通常你会看到有人在启动类中使用@Bean注解生成一个实例对象。

    1598407594516

    (3)@ComponentScan

    用于完成组件(@Component,@Controller,@Service,@Repository)扫描。不过需要注意,其仅仅用于配置组件扫描指令,并没有真正扫描,更没有装配其中的类,这个真正扫描是由@EnableAutoConfiguration 完成的。

    注意一点:Spring Boot1.x 版本中仅会扫描当前标注类所在包的子孙包,不会扫描标注类所在的包。但 Spring Boot2.x 版本中默认会扫描当前注解所标注类所在的包及其子孙包。

    (4)@EnableAutoConfiguration

    @EnableAutoConfiguration表示开启自动配置功能。@EnableXxx 注解一般用于开启某一项功能,是为了简化代码的导入,即使用了该类注解,就会自动导入某些类。所以该类注解是组合注解,一般都会组合一个@Import 注解,用于导入指定的多个类,而被导入的类一般分为三种:配置类、选择器,与注册器。@import注解中导入的类可以认为是具体的配置功能实现类,也可以理解为是框架内部需要使用的Bean。

    1598409693267

    举例说明@Import导入类(了解):

    A、配置类

    @Import 中指定的类一般以 Configruation 结尾,且该类上会注解@Configuration,表示当前类为一个配置类。

    1598409847148

    1598409886148

    B、选择器

    @Import 中指定的类一般以 Selector 结尾,且该类实现了 ImportSelector 接口,表示当前类会根据条件选择要导入的类。

    1598410003403

    C、注册器

    @Import 中指定的类一般以 Registrar 结尾,且该类实现了 ImportBeanDefinitionRegistrar接口,用于导入注册器,该类可以在代码运行时动态注册指定类的实例。

    1598410081817

    (5)引申(了解)

    @import、@ImportResource、@PropertySource三个注解都是用于导入配置,有什么区别呢?

    @import注解可以将普通类导入到spring容器中做管理;

    @ImportResource(locations={}),与@import功能相似。只不过导入的是包含有definition配置的xml文件,而不是类。

    @PropertySource可以导入property(key-value)文件到Spring容器中,用法:

    @PropertySource("classpath:/com/myco/app.properties")
    public class AppConfig {
        @Autowired
        Environment env;
        
        @Bean
        public TestBean testBean() {
            TestBean testBean = new TestBean();
            testBean.setName(env.getProperty("testbean.name"));
            return testBean;
        }
    }
    

    二、解析@EnableAutoConfiguration

    1598410278957

    该注解用于开启自动配置,是 Spring Boot 的核心注解,是一个组合注解。所谓自动配置是指,其会自动找到其所需要的类,然后交给 Spring 容器完成这些类的装配。

    • @Import:用于加载 Spring Boot 中内置的及导入 starter 中 META-INF/spring.factories配置中的自动配置类。
    • @AutoConfigurationPackage:用于扫描、加载并注册自定义的组件类。
    (1)@Import(AutoConfigurationImportSelector.class)

    追踪 AutoConfigurationImportSelector的源码,我们可以发现确实是加载META-INF/spring.factories中的配置。

    1598410729322

    1598410802537

    1598410828686

    那么这个META-INF/spring.factories文件在哪里呢。所有的项目都依赖于spring-boot-starter,而spring-boot-starter又依赖于spirng-boot-autoconfigure,通过查看pom可以发现:

    1598414704522

    所以,我们在jar包中寻找spirng-boot-autoconfigure,

    1598414798893

    在spring.fatories中就看到一些默认的配置类,

    keyorg.springframework.boot.autoconfigure.EnableAutoConfiguration

    value配置类全路径

    1598414898402

    (2)@AutoConfigurationPackage

    用于导入用户自定义类(即业务实现类),即自动扫描包中的类。

    三、starter认知

    通过以上的介绍,我们已经能够大致猜到在spring boot中是如何通过一个starter自动配置对象的了。

    ①通过@EnableAutoConfiguration读取到META-INF/spring.factories,这里边注册了所有需要加载的bean对应的配置类的全路径;

    ②spring会根据反射的原理,读取到配置类中使用@Bean声明的BeanDefinition,进而生成Bean对象放到IOC容器中。


    通过以下两个例子我们再体会一下starter的配置。

    (1)sping boot与redis整合

    1598418337043

    通过查看RedisAutoConfiguration,我们可以发现在此处创建了RedisTemplate实例。

    1598418650854

    (2)mybatis与spring boot整合

    在 External Libraries 中找到 mybatis-spring-boot-starter 依赖。而该依赖又依赖于mybatis-spring-boot-autoconfigurigure。其 META-INF 中就有 spring.factories 文件,打开这个文件我们找到了 Mybatis 的自动配置类。

    1598418809642

    1598418857161

    1598418901915

    15984189834711598419001286

    可以验证,我们以上的猜想starter=>spring.factories=>配置类=>生产Bean是正确的。

    细心的人一定发现了以上有好多ConditionalOn开头的注解,它们是干什么用的呢?见名知意,没错,它们被称之为条件注解,只有符合注解条件时才会执行对应方法生成相应的Bean实例。

    四、条件注解

    常见的条件注解有:

    @ConditionalOnClass():条件判断注解,其可以标注在类与方法上,表示当参数指定的类在类路径下存在时才会创建当前类的 Bean,或当前方法指定的 Bean。

    @ConditionalOnMissionBean:条件判断注解,其可以标注在类与方法上,表示当容器中不存在当前类或方法类型的对象时,将去创建一个相应的 Bean。

    @ConditionalOnBean():条件判断注解,其可以标注在类与方法上,表示当在容器中存在指定类的实例时才会创建当前类的 Bean,或当前方法指定的 Bean。

    @ConditionalOnProperty():条件判断注解,其可以标注在类与方法上,表示配置文件中指定的属性满足条件时才会创建当前类的 Bean,或当前方法指定的 Bean。

    五、手写一个starter

    至此,我们应该可以手写一个starter了。可参考另一篇博客:

    https://www.cnblogs.com/zomicc/p/13564586.html

    "我们所要追求的,永远不是绝对的正确,而是比过去的自己更好"
  • 相关阅读:
    Go-常量-const
    centos-安装python3.6环境并配置虚拟环境
    centos-环境变量配置
    linux_命令格式和命令提示符
    linux_基础调优
    使用 Docker 容器应该避免的 10 个事情
    Linux--多网卡的7种Bond模式和交换机配置
    《Linux内核精髓:精通Linux内核必会的75个绝技》目录
    《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #21FUSE
    《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #20 使用fio进行I/O的基准测试
  • 原文地址:https://www.cnblogs.com/zomicc/p/13564585.html
Copyright © 2011-2022 走看看