SpringBoot - 浅析自动装配过程及相关注解

前言

在Spring阶段,我们被各种XML文件配置或者配置类所困扰着,Spring有着“配置地狱”之称

为了简化新 Spring 应用的初始搭建以及开发过程,提出了自动装配的SpringBoot,
该框架遵循“约定优于配置”,使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置


约定优于配置

约定优于配置:按照约定的规范编程,而不是按照配置

以Spring+Mybatis为例:

需要3个文件:Spring基本配置文件(设置自动扫描等)、mybatis配置文件(可以省略)、Spring+mybatis配置文件(bean装配mybatis配置)
在这里插入图片描述

mybatis连接数据库的配置必不可少:

    <!--DataSource:使用Spring的数据源替换Mybatis的配置
        使用spring提供的jdbc
    -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <!--绑定Mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--绑定Mapper文件-->
        <property name="mapperLocations" value="classpath:com/learn/dao/UserMapper.xml"/>
    </bean>

    <!--SqlSessionTemplate就是我们使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能构造器注入,没有setter方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

而在SpringBoot+Mybatis:

一个application.yml配置文件即可
在这里插入图片描述

只需稍微配置:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver


mybatis:
  type-aliases-package: com.learn.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

为什么这么简单就配置好了?

因为在SpringBoot中设置了默认约定,SpringBoot会自动装配好我们需要的东西
如果需要自定义一些配置,在yml文件中配置,即开发人员仅需规定应用中不符合约定的部分,在没有规定配置的地方,采用默认配置

SpringBoot中有哪些约定呢?

  • Maven的目录结构:src-main-resources,src-main-java,resources文件夹,存放资源配置文件,java文件夹存放java程序,必须要SpringbootApplication.java同层才能运行。默认的编译生成的类都在targe文件夹下面
  • springboot默认的配置文件必须是application.命名的yml文件或者properties文件(可以通过加上-后缀设置不同文件:application-dev.yml)
  • application.yml中设置属性需要按层次格式,Spring->datasource->url;mybatis->type-aliases-package等

@SpringBootApplication

SpringBoot有一个启动类SpringbootApplication

package com.springbootweb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Springbootweb01Application {

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

这是SpringBoot的入口,SpringBoot的启动就是从该main方法启动

它主要加载了@SpringBootApplication注解主配置类

来分析@SpringBootApplication注解

在这里插入图片描述

上面四个是元注解,下面的3个是我们需要关注的注解

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM,
    classes = TypeExcludeFilter.class), @Filter(type =
    FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

@SpringBootConfiguration较简单:
在这里插入图片描述

在Spring中就学了,@Configuration注解表示该类为Spring的配置类
这个@SpringBootConfiguration注解功能一样的


@EnableAutoConfiguration

EnableAutoConfiguration,直白的名字:开启自动配置
分析:

在这里插入图片描述

该注解上有两个重要的注解:

  • @AutoConfigurationPackage:添加该注解的类所在的package作为自动配置package进行管理

  • @Import(AutoConfigurationImportSelector.class):导入了一个
    AutoConfigurationImportSelector选择器给Spring容器中来导入一些组件

@AutoConfigurationPackage注解:导入AutoConfigurationPackages.Registrar注册器
在这里插入图片描述

在这里插入图片描述

{ @link ImportBeanDefinitionRegistrar } to store the base package from the importing configuration.

就不深入解析了,该注解大致的意思就是:当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package,所以说我们的包应当和SpringBootApplication类同层

在这里插入图片描述

@Import(AutoConfigurationImportSelector.class)

版本为2.2.6 RELEASE,不同的版本有一定的更改

父类里面规定了一个方法叫selectImports方法,查看了selectImports这个方法里面的代码内容就能知道导入了哪些组件:
在这里插入图片描述

调用了getAutoConfigurationEntry方法,顾名思义:获得自动装配组件

在这里插入图片描述

该方法会返回configurations,这个就是配置对象集合

通过getCandidateConfigurations方法获得,获得候选配置

在这里插入图片描述

SpringFactoriesLoader.loadFactoryNames是这里关键的方法,Spring工厂加载类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

该方法会扫描具有META-INF/spring.factories文件的jar包,把这个文件的urls拿到之后并把这些urls遍历,最终把这些文件整成一个properties对象

然后它从properties对象里边获取一些值,把这些获取到的值来加载我们最终要返回的这个结果result,result就是我们要交给Spring容器中的所有组件

factoryTypeName就是我们传过来的Class的这个类名。

是前面SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()),传入的getSpringFactoriesLoaderFactoryClass()方法中得到,从properties中获取到EnableAutoConfiguration.class类名:
在这里插入图片描述
SpringFactoriesLoader会根据这个EnableAutoConfiguration.class去spring.factories找EnableAutoConfiguration.class所对应的values,并返回

在这里插入图片描述


spring.factories

META-INF/spring.factories文件在Spring-boot-autuoconfigure包下
在这里插入图片描述

这个配置文件配置了很多自动装配的信息:
在这里插入图片描述

这些自动装配类xxxAutoConfiguration都是SpringBoot自动装配的相关类,是SpringBoot自动装配的核心

每个xxxAutoConfiguation类都定义了相关bean的实例化配置,说明了哪些bean可以被自动配置,什么条件下可以自动配置,并把这些bean实例化出来

我们打开一个常见的DataSourceAutoConfiguration,进入查看

在这里插入图片描述

  • @Configuration(proxyBeanMethods = false):表明这是一个配置类,proxyBeanMethods = false表示该类不会被代理,提供性能
  • @ConditionalOnClass:当SpringIoC容器内存在指定Class的条件,表示对应的jar包是否导入了,这类注解用来判断是否执行自动装配
  • @EnableConfigurationProperties(DataSourceProperties.class):导入对应的启动装配属性类:DataSourceProperties
  • @Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class }):相关的配置类

主要就是DataSourceProperties,这个类中定义自动装配的配置:

在这里插入图片描述
表示配置前缀是:spring.datasource

内部属性有:
在这里插入图片描述

这些就是在application.yml文件中自定义配置的属性:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

到这,应该明白了 spring.factories的作用:

  • 在该文件中配置好SpringBoot需要的自动配置类,当启动SpringBoot时会加载该文件,并一个个加载这些xxxAutoConfiguration类
  • 而在这些类中,会有一类ConditionalOnXxx注解判断该类是否自动装配
  • 如果是自动装配,会加载EnableConfigurationProperties注解导入的Properties类,该类中会有成员变量,这些变量对应着yml文件可以设置的字段

总结

我们可以大致总结自动配置:

  • SpringBootApplication启动类,是SpringBoot程序的入口,关键在与@SpringBootApplication注解

  • 该注解有两个重要的元注解:@SpringBootConfiguration表示该类为Spring的配置类;@EnableAutoConfiguration

  • @EnableAutoConfiguration有两个重要元注解:
    @AutoConfigurationPackage表示当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package
    @Import(AutoConfigurationImportSelector.class)导入了一个选择器

  • AutoConfigurationImportSelector的selectImports方法决定SpringBoot导入的组件,经过一系列的方法调用最终会使用SpringFactoriesLoader加载器负责加载配置类名,loadSpringFactories方法读取自动配置工程的META-INF/spring.factories配置文件,加载配置类的全类名,包装成Properties对象,返回result就是交给Spring容器的组件

  • spring.factories内部编写好了全部的自动装配类,启动SpringBoot时,会加载这些自动装配类xxxAutoConfiguration,这些自动装配类有元注解ConditionalOnXxx判断是否自动装配,如果判断确定自动装配,会加载相关的Properties属性类,该属性类属性字段对应yml文件中的字段

学海无涯苦作舟

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值