简述SpringBoot Starter原理及自定义实现

x33g5p2x  于2021-09-19 转载在 Spring  
字(4.2k)|赞(0)|评价(0)|浏览(503)

一、简述

SpringBoot Starter是一组方便的依赖描述符,一个启动器。可以看成一个入口,通过这个入口,整合其他的模块,使得我们开发中不需要到处写配置或者在基础模块中加各种依赖,让配置和依赖的处理变得更简单。
Spring Boot Starter的实现,需要完成两件事:
----引入模块所需的相关jar包
----自动装配模块所需的配置到容器

命名规则
1、通过官网查看,官方提供了44个依赖,官方遵循命名模式:
前缀固定:spring-boot-starter-xxx,其中xxx是特定类型的应用程序,此命名结构目的在需要查找入门时提供帮助。
例如:
spring-boot-starter-web 基于Spring MVC 构建 Web应用容器。使用 Tomcat 作为默认的嵌入式容器
spring-boot-starter-jdbc 数据库连接模块
spring-boot-starter-test 包括 JUnit、Mockito 在内的库测试应用程序

自定义命名
以模块名称开头,后缀固定:xxx-spring-boot-starter
例如:mybatis-spring-boot-starter

二、结合SpringBoot启动原理看容器如何实现自动装配

SpringBoot的启动简单来说是通过注解来表示或者通过配置文件的方式找到需要装配的类,然后通过调用run()方法加载注入bean,此处主看主类的注解@SpringBootApplication,点进此注解,可以发现是一个复合注解。

重点看三个注解:
@Configuration(在注解@SpringBootConfiguration里),被@Configuration标注的类表示是spring容器的配置类

@ComponentScan
扫描指定路径下符合条件的bean,在容器启动过程中,将这些bean加载到容器中,其扫描默认的范围是启动类所在包及其子级包下的文件。

@EnableAutoConfiguration
主关注此注解下两个注解
一个是@AutoConfigurationPackage ,点进去看 @Import({Registrar.class})
通过Registrar.class 将@ComponentScan扫描到的类在容器启动过程中将bean注入到Spring容器(具体加容器加载过程此处不做详述)。

另一个是 @Import({AutoConfigurationImportSelector.class})
看源码可知通过EnableAutoConfigurationImportSelector找到类SpringFactoriesLoader来 搜索所有的META-INF/spring.factories配置文件,然后将其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value值加载到spring容器中。

由此可看出,对于springboot提供的其他模块配置的装配,其通过文件META-INF/spring.factories来加载,starter关于配置的自动装配,即从此处入手

三、解析mybatis-spring-boot-starter包看mybatis的集成

maven依赖:

<dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.0.0</version>
    </dependency>

查看starter类,里面依赖了Mybatis所需的jar包,除此之外,有一个负责自动配置的配置包,
mybatis-spring-boot-autoconfigure.jar

通过查看spring.factories,其Mybatis的配置,
key:org.springframework.boot.autoconfigure.EnableAutoConfiguration
value是:org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
(values值多个以逗号(“,”)相隔 ,每个value为一个配置类)

@ConditionalOnClass 表示在类存在的情况下进行自动配置
@EnableConfigurationProperties,使@ConfigurationProperties注解生效,把 MybatisProperties注入入到 IOC 容器中。
@AutoConfigureAfter,完成自动配置后实例化这个bean

通过查看mybatis-spring-boot-starter,可以发现starter包很简单,没有class文件,只是把starter当做一个相对完整的模块的入口,通过pom文件引入其模块依赖的jar包和配置包,在项目上需要使用此模块时,只需引入这个依赖即可。

四、自定义Spring Boot Starter

创建三个模块
(1)自动配置模块:demo-spring-boot-autoconfigure
(2)starter模块:demo-spring-boot-starter
(3)测试模块:demoTest

1、建立demo-spring-boot-autoconfigure模块,其项目结构如下

2、提供一个供外部配置的属性类DemoProperties.java,通过@ConfigurationProperties注解标识,其表示该类的参数从配置文件application.properties或application.yml里面读取,prefix = "demo"表示配置文件里参数的前缀。

package com.tyn.demoConfigure.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 自动配置相关属性的入口,通过注解ConfigurationProperties标识配置
 */
@Data
@ConfigurationProperties(prefix = "demo")
public class DemoProperties {
    private String proName;
    private String proData;
}

3、通过配置类DemoAutoConfiguration.java将属性类注入到spring容器中,通过注解@EnableConfigurationProperties注入,以下DemoService作为一个测试bean

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {

    @Autowired
    DemoProperties demoProperties;

    @Bean
    public DemoService helloService(){
        return new DemoService();
    }
}

4、配置中注入的bean:DemoService.java

/**
 * 注意,此处不需要注解@Service,因为已通过DemoAutoConfiguration注入bean
 * @return
 */
public class DemoService {

    @Autowired
    private DemoProperties demoProperties;

    public String getPropertiesVal(String paramVal) {
       return "paramVal:" + paramVal + "; proName:"+ demoProperties.getProName() + "; proDate:" + demoProperties.getProData();
    }
}

5、配置类SpringFactoriesLoader扫描的spring.factories文件,指定需要扫描的配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tyn.demoConfigure.configure.DemoAutoConfiguration

6、测试无误后将配置模块install/deploy到仓库

7、建立demo-spring-boot-starter模块,pom文件里引入demo-spring-boot-autoconfigure的依赖

<dependency>
   <groupId>com.tyn</groupId>
   <artifactId>demo-spring-boot-autoconfigure</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>

8、demo-spring-boot-starter模块无误后install/deploy到仓库

9、测试模块:demoTest,把starter包demo-spring-boot-starter依赖进来

<dependency>
   <groupId>com.tyn</groupId>
   <artifactId>demo-spring-boot-starter</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>

10、启动测试模块测试

作者:yana

相关文章