美文网首页程序员Java
Spring Boot 自动配置原理详解

Spring Boot 自动配置原理详解

作者: 一个小素 | 来源:发表于2019-09-30 11:02 被阅读0次

    小伙伴们是否想起曾经被 SSM 整合支配的恐惧?相信很多小伙伴都是有过这样的经历的,一大堆配置问题,各种排除扫描,导入一个新的依赖又得添加新的配置。自从有了 Spring Boot 之后,咱们就起飞了!各种零配置开箱即用,而我们之所以开发起来能够这么爽,自动配置的功劳少不了,今天我们就一起来讨论一下 Spring Boot 自动配置原理,看完心里有个大概,不至于被面试官问的面红耳赤。

    1. SpringBoot 源码常用注解

    这部分主要讲一下 SpringBoot 源码中经常使用到的注解,以扫清后面阅读源码时候的障碍。

    组合注解

    当可能大量同时使用到几个注解到同一个类上,就可以考虑将这几个注解到别的注解上。被注解的注解我们就称之为组合注解。

    • 元注解:可以注解到别的注解上的注解。
    • 组合注解:被注解的注解我们就称之为组合注解。

    @Value

    @Value 就相当于传统 xml 配置文件中的 value 字段。

    假设存在代码:

    @Component public class Person { 
    @Value("i am name") private String name; 
    }
    
    

    上面代码等价于的配置文件:

    <bean class="Person"> <property name ="name" value="i am name"></property></bean>
    
    

    我们知道配置文件中的 value 的取值可以是:

    • 字面量
    • 通过 ${key}方式从环境变量中获取值
    • 通过 ${key}方式全局配置文件中获取值
    • {SpEL}

    所以,我们就可以通过 @Value(${key})的方式获取全局配置文件中的指定配置项。

    @ConfigurationProperties

    如果我们需要取 N 个配置项,通过@Value的方式去配置项需要一个一个去取,这就显得有点 low 了。我们可以使用@ConfigurationProperties。标有@ConfigurationProperties的类的所有属性和配置文件中相关的配置项进行绑定。(默认从全局配置文件中获取配置值),绑定之后我们就可以通过这个类去访问全局配置文件中的属性值了。

    @Import

    @Import 注解支持导入普通 java 类,并将其声明成一个bean。主要用于将多个分散的 java config 配置类融合成一个更大的 config 类。

    • @Import 注解在 4.2 之前只支持导入配置类。
    • 在4.2之后 @Import 注解支持导入普通的 java 类,并将其声明成一个 bean。

    @Import 三种使用方式

    • 直接导入普通的 Java 类。
    • 配合自定义的 ImportSelector 使用。
    • 配合 ImportBeanDefinitionRegistrar 使用。

    @Conditional

    @Conditional 注释可以实现只有在特定条件满足时才启用一些配置。

    除了自定义 Condition,Spring 还为我们扩展了一些常用的 Condition。

    Java方面的架构资料,我这里刚好有一份,怎么领取→→→关注+转发 然后私信“架构资料” 即可领取

    2. SpringBoot 自动配置原理

    要了解SpringBoot自动化配置原理就要首先来看一下SpringbootDemoApplication.java。

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

    我们可以看到这个类中最耀眼的就属@SpringBootApplication注解了,我们点进去看一下@SpringBootApplication的源码。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
     @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
     @Filter(type = FilterType.CUSTOM,
     classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication { } 
    

    @Target,@Retention,@Documented,@Inherited四个注解属于元注解,与自动配置无关,我们不再讲解。

    @SpringBootConfiguration

    @EnableAutoConfiguration

    @ComponentScan

    是SpringBootApplication的核心注解,SpringBoot的启动类如果使用这三个注解也可以正常启动,SpringBoot帮我们做了简化。

    @SpringBootConfiguration注解:

    我们先来看看@SpringBootConfiguration注解的源码。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration {
    }
    
    

    @SpringBootConfiguration 与@Configuration并没有任何区别,@Configuration可以标注当前类是一个配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到Spring IOC容器中。

    @EnableAutoConfiguration注解:

    The second class-level annotation is @EnableAutoConfiguration. This annotation tells Spring Boot to “guess” how you <br>will want to configure Spring, based on the jar dependencies that you have added. Since spring-boot-starter-web added Tomcat and Spring MVC, <br>the auto-configuration will assume that you are developing a web application and setup Spring accordingly.<br><br>
    Starters and Auto-Configuration
    Auto-configuration is designed to work well with “Starters”, but the two concepts are not directly tied. <br>You are free to pick-and-choose jar dependencies outside of the starters and Spring Boot will still do <br>its best to auto-configure your application.
    
    

    这个注释告诉SpringBoot“猜”你将如何想配置Spring,基于你已经添加jar依赖项。如果spring-boot-starter-web已经添加Tomcat和Spring MVC,这个注释自动将假设您正在开发一个web应用程序并添加相应的spring设置。

    自动配置被设计用来和“Starters”一起更好的工作,但这两个概念并不直接相关。您可以自由挑选starter依赖项以外的jar包,springboot仍将尽力自动配置您的应用程序。

    spring通常建议我们将main方法所在的类放到一个root包下,@EnableAutoConfiguration(开启自动配置)注解通常都放到main所在类的上面,下面是一个典型的结构布局:

    com
     +- example
     +- myproject
     +- Application.java
     |
     +- domain
     | +- Customer.java
     | +- CustomerRepository.java
     |
     +- service
     | +- CustomerService.java
     |
     +- web
     +- CustomerController.java
    
    

    这样@EnableAutoConfiguration可以从逐层的往下搜索各个加注解的类,例如,你正在编写一个JPA程序(如果你的pom里进行了配置的话),spring会自动去搜索加了@Entity注解的类,并进行调用

    @ComponentScan注解:

    @ComponentScan注解是我们非常熟悉的一个注解,@ComponentScan的功能就是自动扫描并加载符合条件的组件或Bean定义,最终将这些bean定义加载到当前使用的容器中。

    通过以上三个注解,SpringBoot便完成了它的自动化配置,你看明白了吗?

    至此,我们可以总结一下Spring Boot的自动化配置的实现:

    相关文章

      网友评论

        本文标题:Spring Boot 自动配置原理详解

        本文链接:https://www.haomeiwen.com/subject/mxfbuctx.html