首页 > 其他分享 >springboot starter 原理解析及实践

springboot starter 原理解析及实践

时间:2023-02-15 21:24:26浏览次数:38  
标签:DemoHelloService springboot class defaultMsg msg 解析 public starter

什么是springboot starter

starter是springBoot的一个重要部分。通过starter,我们能够快速的引入一个功能,而无需额外的配置。同时starter一般还会给我提供预留的自定配置选项,我们只需要在application.properties中设置相关参数,就可以实现配置的个性化。

那么这些方便的操作是怎么实现的呢?通过了解其原理,我们也可以做一个自己的starter,来让别人快速使用我们的功能。

按个人理解,我认为springBoot Starter就是一个智能化的配置类@Configuration

接下来介绍内容包括:

  • 快速写一个starter demo。
  • 解释其中的原理。

一、快速写一个starter模块试试

1、【创建module】,首先我们自定义一个starter的module,根据你的starter实现复杂度,引入相关spring组件。最基本的,我们只需引入spring-boot-autoconfigure模块。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.linjianhui.springboot</groupId>
    <artifactId>examplestarter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <name>examplestarter</name>
    <description>Demo project for Spring Boot starter</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.3.0.RELEASE</version>
        </dependency>
    </dependencies>
</project>

2、【业务bean实现】实现我们的业务bean,案例中我们实现最简单的sayHello服务,输入msg,返回“hello,{msg}”。

public class DemoHelloService {
    private String defaultMsg = "";

    public String sayHello(String msg) {
        return "hello, " + ((msg == null || msg.isEmpty()) ? defaultMsg : msg);
    }

    public void setDefaultMsg(String defaultMsg) {
        this.defaultMsg = defaultMsg;
    }
}

3、然后就是Configuration类的创建,这个类是starter自动初始化的核心类,负责把业务相关的bean智能的加载进来。

@Configuration
@ConditionalOnClass(DemoHelloService.class)
public class HelloDemoAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(DemoHelloService.class)//如果用户未自定义相关bean,生成默认bean
    public DemoHelloService demoHelloService() {
        DemoHelloService demoHelloService = new DemoHelloService();
        return demoHelloService;
    }
}

4、配置spring.factories,通过该配置,才能让springboot来自动加载我们的Configuration类。具体原理我们稍后深入了解。

具体的,是在模块的resources/META-INF 目录下,新建spring.factories文件。内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xxx.springboot.examplestarter.HelloDemoAutoConfiguration

最后我们把上述模块单独执行以下install或者deploy,一个starter就做好了。

其他项目使用我们的starter就非常简单了:(1)引入starter依赖;(2)注入需要的service。

    <dependencies>
        。。。
        <dependency>
            <groupId>com.xxx.springboot</groupId>
            <artifactId>examplestarter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    。。。
@RestController
public class GreetingController {
    @Resource
    private DemoHelloService demoHelloService;

    @RequestMapping("/sayhello")
    public String sayHello(String msg) {
        return demoHelloService.sayHello(msg);
    }

done!

 

 

二、starter原理解读

回头再看上边的开发流程,有两个地方需要我们了解一下:

(1)如何让starter被自动识别加载:spring.factories里的EnableAutoConfiguration原理。

(2)如何实现自动加载的智能化、可配置化:@Configuration配置类里注解。

1.配置类自动加载机制

这里我们只简单的说一下大致的原理和流程,执行细节大家可以按照文章给出的思路自己去研读。

在SpringBoot的启动类,我们都会加上@SpringBootApplication注解。这个注解默认会引入@EnableAutoConfiguration注解。然后@EnableAutoConfiguration@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector.class的selectImports方法最终会通过SpringFactoriesLoader.loadFactoryNames,加载META-INF/spring.factories里的EnableAutoConfiguration配置值,也就是我们上文中设置的资源文件。

2.自动加载的智能化可配置化

实际使用中,我们并不总是希望使用默认配置。比如有时候我想自己配置相关功能,有时候我想更改一下默认的服务参数。这些常见的场景Starter都想到了,并提供了如下的解决方案:

(1)@Conditional*注解

springboot starter提供了一系列的@Conditional*注解,代表什么时候启用对应的配置,具体的可以去查看一下springboot的官方文档。

比如我们案例中的 「@ConditionalOnClass(DemoHelloService.class)」,代表如果存在DemoHelloService类时,配置类才会生效;又比如「@ConditionalOnMissingBean(DemoHelloService.class)」,代表着如果项目中没有DemoHelloService类型的bean,那么该配置类会自动创建出starter默认的DemoHelloService类型bean。

(2)@ConfigurationProperties注解

这个注解主要是为了解决如下场景:我想要使用starter的默认配置类,但是又想对配置中的某些参数进行自定义配置。@ConfigurationProperties类就是做这个工作的。例如上述例子中,我想对默认的defaultMsg做些个性化的设置。就可以按如下方式来实现:

starter新增ConfigurationProperties类bean

@ConfigurationProperties(prefix = "hello.demo")
public class HelloDemoProperties {
    private String defaultMsg = "";

    public String getDefaultMsg() {
        return defaultMsg;
    }

    public void setDefaultMsg(String defaultMsg) {
        this.defaultMsg = defaultMsg;
    }
}

启用property

在实际项目中自定义默认msg

 

 

当我们不输入msg值时,默认表现行为如下:

 

 

 

标签:DemoHelloService,springboot,class,defaultMsg,msg,解析,public,starter
From: https://www.cnblogs.com/hanease/p/17124714.html

相关文章

  • springboot切换web服务器
    <?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:s......
  • SpringBoot整合MyBatis
    SpringBoot整合MyBatis在pom文件中添加以下坐标,增加mybatis依赖,和数据库驱动依赖<!--导入Mybatis依赖坐标--><dependency><groupId>org.mybatis.spring.boot</gr......
  • SpringBoot注册Servlet、Filter和Listener的方式和原理
    1实战在SpringBoot项目中,如果使用内嵌Web服务器,可以很方便地注册Servlet、Filter和Listener等组件。总的来说,包括以下方式:创建实现ServletContextInitializer接口的b......
  • SpringBoot---起步依赖starter
    1、简化spring应用的初始搭建和开发过程。springboot程序优点:自动配置、起步依赖(简化依赖配置)、辅助功能(内置服务器...)<?xmlversion="1.0"encoding="UTF-8"?><pro......
  • SpringBoot-----quickstart
    一、最简SpringBoot程序所包含的基础文件:pom.xml和Application类。spring官网同样可以快速构建springboot工程。 二、SpringBoot项目快速启动1、在lifecycle中双击pac......
  • SpringBoot文件上传丢失Bug记录
    SpringBoot文件上传丢失Bug记录报错如下:java.io.FileNotFoundException:C:\Users\zbz12\AppData\Local\Temp\tomcat.708075972435741143.8080\work\Tomcat\localhost\c......
  • AOP全面解析
    转载:SpringAOP全面详解(超级详细)_鸨哥学JAVA的博客-CSDN博客_springaop转载:SpringAOP全面详解(超级详细)_鸨哥学JAVA的博客-CSDN博客_springaop转载:SpringAOP全面详......
  • 【Spring IOC】【二】容器源码解析- 获取单例 Bean
    1 前言在本篇文章中,我们将会详细分析BeanFactory的getBean(String)方法实现细节及所调用的方法。2 源码分析首先我们先通读一下doGetBean方法,了解里边重点的几个步......
  • springboot在test的时候,new的类报空指针
    ok@ComponentpublicclassFifthGithubCrawler{@AutowiredprivateKBComponentVersionRepositoryversionRepository;/***导出所有数据到json......
  • [经验] 使用Python解析Xml文件常用办法(xml库)
    常使用python自带xml库解析xml文件,过程如下:1.使用xml.etree.ElementTree库的ET.parse()函数解析XML文件。2.遍历XML文件中的所有<object>元素,并提取每个对象的类别和......