Spring Boot源码解析(三)

前言

开发spring boot应用的时候,你一定引用过spring-boot-starter,spring-boot-starter-web类似这样的包,你也一定引用过druid-spring-boot-starter类似这样的包。为啥他们的命名,一种是spring-boot-starter-XXX,而另一种是XXX-spring-boot-starter呢,他们有什么区别吗?其实区别呢,就是前一种是spring boot去整合的一些类库,而后一种是第三方去主动整合的spring boot的一些类库,换句话说,就是自定义的starter。今天和小编一起来开发专属于你自己的starter吧!

需求

开工前,那必须先确定需求。永远经典的只有"hello world"。下面我们实现的自定义starter实现一个功能是:用户输入用户名,加上前缀:hello world,再加上后缀:你好。而前辍与后辍定义在 yml 或 properties 配置文件中。例如,用户输入的用户名为 lyj, 则最终输出为hello world, lyj, 你好!

实现

新建starter工程

初始化一个spring boot工程

命名为hello-spring-boot-starter,引入pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

定义HelloService

该类是starter的核心类,主要是实现需求中的字符串拼接的功能(即业务功能)

/**
 * 自定义starter核心类
 * @author:liyajie
 * @createTime:2022/1/26 14:11
 * @version:1.0
 */
@AllArgsConstructor
public class HelloService {
    private String prefix;
    private String suffix;

    public String sayHello(String userName){
        return prefix + "," + userName + "," + "你好!";
    }
}

定义HelloServiceProperties

该类主要是封装了前缀和后缀两个属性,用来接收外部传进来的属性参数

/**
 * HelloService属性封装类
 * @author:liyajie
 * @createTime:2022/1/26 14:15
 * @version:1.0
 */
@Data
@ConfigurationProperties("hello")
public class HelloServiceProperties {
    private String prefix;
    private String suffix;
}

定义HelloServiceAutoConfiguration

该类主要是自动装配类,即将HelloService和HelloServiceProperties关联起来,将HelloServiceProperties接收到的参数,传给HelloService核心类,利用构造函数生成合适的HelloService对象

/**
 * 自动装配类
 * @author:liyajie
 * @createTime:2022/1/26 14:23
 * @version:1.0
 */
@Configuration
@ConditionalOnClass(HelloService.class)
@EnableConfigurationProperties(HelloServiceProperties.class)
public class HelloServiceAutoConfiguration {
    @Autowired
    private HelloServiceProperties helloServiceProperties;

    @Bean
    public HelloService helloService(){
        return new HelloService(helloServiceProperties.getSuffix(), helloServiceProperties.getSuffix());
    }
}

创建 spring.factories 文件

在starter项目的resources目录下创建/META-INF/spring.factories文件,里面只有一行键值对的配置,标识HelloServiceAutoConfiguration自动装配 即:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lyj.hello.config.HelloServiceAutoConfiguration

maven install

执行maven install命令,将我们的自定义hello-spring-boot-starter安装到我们本地的maven仓库里

测试

创建测试工程,引入我们的hello-spring-boot-starter依赖

<dependency>
    <groupId>com.lyj.hello</groupId>
    <artifactId>hello-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

编写测试接口,核心代码如下:

/**
 * 测试类
 * @author:liyajie
 * @createTime:2022/1/26 14:36
 * @version:1.0
 */
@RestController
public class TestController {

    @Autowired
    private HelloService helloService;

    @GetMapping("/sayHello/{username}")
    public String sayHello(@PathVariable("username") String username){
        return helloService.sayHello(username);
    }
}

请求接口,查看结果

可以看到我们已经实现了需求,完美!

image.png

小优化

虽然我们实现了自定义starter,可以拼接我们的用户名和前后缀,有点low,那么我们可不可以设置一个开关,当开关打开的时候,我们就拼接用户名和前后缀;当开关关闭的时候,我们就直接返回用户名呢!你认为可以实现吗?下篇文章我们继续分析!

需要源码的可以关注公众号【温故知新之java】,更多干活与你分享。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容