关于java:徒手撸一个Spring-Boot中的starter

43次阅读

共计 4045 个字符,预计需要花费 11 分钟才能阅读完成。

starter 背景

Spring Boot 目前曾经变成了后端开发这必备技能之一,其中一个次要起因是 Spring Boot 中有个十分重要的机制(starter 机制)。

starter 可能摈弃以前繁冗的配置,将其对立集成进 starter,应用的时候只须要在 maven 中引入对应的 starter 依赖即可,Spring Boot 就能主动扫描到要加载的信息并启动相应的默认配置。

starter 让咱们解脱了各种依赖库的解决,以及各种配置信息的懊恼。SpringBoot 会主动通过 classpath 门路下的类发现须要的 Bean,并注册进 IOC 容器。Spring Boot 提供了针对日常企业应用研发各种场景的 spring-boot-starter 依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并容许咱们调整这些配置,即遵循“约定大于配置”的理念。

[[金三银四,如何涨薪看这里]](http://mp.weixin.qq.com/s?__b…

咱们常常会看到或者应用到各种 xxx-starter。比方上面几种:

Spring Boot starter 原理

从总体上来看,无非就是将 Jar 包作为我的项目的依赖引入工程。而当初之所以减少了难度,是因为咱们引入的是 Spring Boot Starter,所以咱们须要去理解 Spring Boot 对 Spring Boot Starter 的 Jar 包是如何加载的?上面我简略说一下。

SpringBoot 在启动时会去依赖的 starter 包中寻找 /META-INF/spring.factories 文件,而后依据文件中配置的 Jar 包去扫描我的项目所依赖的 Jar 包,这相似于 Java 的 SPI 机制。

细节上能够应用 @Conditional 系列注解实现更加准确的配置加载 Bean 的条件。

JavaSPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动静加载机制。

自定义 starter 的条件

如果想自定义 Starter,首选须要实现自动化配置,而要实现自动化配置须要满足以下两个条件:

  1. 可能主动配置我的项目所须要的配置信息,也就是主动加载依赖环境;
  2. 可能依据我的项目提供的信息主动生成 Bean,并且注册到 Bean 治理容器中;

实现自定义 starter

pom.xml 依赖

<dependencies>
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.0.0.RELEASE</version>
 </dependency>
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <version>2.0.0.RELEASE</version>
    <optional>true</optional>
  </dependency>
</dependencies>

依据须要自定义 Starter 的实现过程大抵如下(以我定义的 Starter 为例):

定义 XxxProperties 类,属性配置类,实现属性配置相干的操作,比方设置属性前缀,用于在 application.properties 中配置。

TianProperties 代码:

import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.tian")
public class TianProperties {
    private String name;
    private int age;
    private String sex = "M";
    // 省略 get set 办法
}

创立 XxxService 类,实现相干的操作逻辑。

TianService 代码:

public class TianService {
    private TianProperties properties;
    public TianService() {}
    public TianService(TianProperties userProperties) {this.properties = userProperties;}
    public void sayHello(){System.out.println("hi, 我叫:" + properties.getName() +
        ", 往年" + properties.getAge() + "岁"
         + ", 性别:" + properties.getSex());
    }
}

定义 XxxConfigurationProperties 类,主动配置类,用于实现 Bean 创立等工作。

TianServiceAutoConfiguration 代码:

@Configuration
@EnableConfigurationProperties(TianProperties.class)
@ConditionalOnClass(TianService.class)
@ConditionalOnProperty(prefix = "spring.tian", value = "enabled", matchIfMissing = true)
public class TianServiceAutoConfiguration {
    @Autowired
    private TianProperties properties;
    @Bean
    @ConditionalOnMissingBean(TianService.class)
    public TianService tianService() {return new TianService(properties);
    }
}

在 resources 下创立目录 META-INF,在 META-INF 目录下创立 spring.factories,在 SpringBoot 启动时会依据此文件来加载我的项目的自动化配置类。

「spring.factories 中配置」

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.tian.TianServiceAutoConfiguration

把下面这个 starter 工程打成 jar 包:

应用自定义 starter

创立一个 Spring Boot 我的项目 test,我的项目整体如下图:

在我的项目中把自定义 starter 增加 pom 依赖

<dependency>
    <groupId>com.tian</groupId>
    <artifactId>spring-boot-tian-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

TestApplication 启动类

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

application.properties 中配置

spring.tian.name=tian
spring.tian.age=22
spring.tian.sex=M

写一个 TestController.java 类

RestController
@RequestMapping("/my")
public class TestController {
    @Resource
    private TianService tianService;
    @PostMapping("/starter")
    public Object starter() {tianService.sayHello();
        return "ok";
    }
}

把咱们自定义的 starter 打成的 jar 依赖进来后,

能够看到其中多了一个 json 的文件。

最初启动我的项目,输出

http://localhost:9091/my/starter

controller 胜利返回 ok,再看后盾打印

hi, 我叫: tian, 往年 22 岁, 性别: M

这就胜利的事实了自定义的 starter。

关键词:开箱即用、缩小大量的配置项、约定大于配置

总结

  1. Spring Boot 在启动时扫描我的项目所依赖的 JAR 包,寻找蕴含 spring.factories 文件的 JAR 包,
  2. 而后读取 spring.factories 文件获取配置的主动配置类 AutoConfiguration`,
  3. 而后将主动配置类下满足条件 (@ConditionalOnXxx) 的 @Bean 放入到 Spring 容器中(Spring Context)
  4. 这样使用者就能够间接用来注入,因为该类曾经在容器中了。

「只有咱们的方向对了,就不怕路远!」

举荐浏览

面试:Zookeeper 常见 11 个连环炮
金三银四,筹备跳槽的看这里!
面试:说说几个常见的 Linux 性能

正文完
 0