SpringBoot学习之路---自定义starter

好久没有更新博客了,今天来记录一下starter的内部依赖原理,并自定义一个starter


starter是个啥,之前我的博客中已经反复提到了,简单来看它是一个场景启动器,一个又一个starter包含了我们所需要的一系列依赖。我们只需要导入它,剩下的一系列maven依赖&各种组件的配置等等,都不需要我们的担心了。

这是为什么呢?

首先先来看看,每个starter内部都会或多或少依赖于别的maven座标,比如spring-boot-starter-jdbc这个场景启动器,它内部依赖于:

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.2.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>3.4.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

主要依赖于jdbchikariCP数据源spring-boot-starter,最后面的这个spring-boot-starter是每个starter都会依赖到的,而前面两个是数据库操作时所需要用到的。

由此可以看出每个starter内部所依赖的maven座标都不尽相同,starter在这里扮演一个"调用者"的角色,负责把其他的所依赖jar包导入进来,如果我们要自定义的话,我们可以根据要应用到的场景从而导入jar包。

而在现实的开发中,我们自定义的starter不仅要完成依赖导入的功能,还要做自动配置组件的工作,就是编写一个自动配置类。这个往往是我们在另外编写一个自动配置模块(和自定义starter不在同一个模块中),之后我们自定义的starter依赖于编写的自动配置模块即可。

现在开始编写代码(starter的pom文件):

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

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

    <!--启动器-->
    <dependencies>

        <!--引入自动配置模块-->
        <dependency>
            <groupId>com.leslie.starter</groupId>
            <artifactId>leslie-spring-boot-starter-autoconfigurer</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

自动配置模块的pom文件:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.atguigu.starter</groupId>
   <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>atguigu-spring-boot-starter-autoconfigurer</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.10.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>

      <!--引入spring-boot-starter;所有starter的基本配置-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>

   </dependencies>



</project>

因为不需要太多功能,所以自动配置模块只引入了一个spring-boot-starter,前期的maven依赖搞定后,我们需要编写一个自动配置类,来帮容器中自动配置组件

该方法需要几个步骤:

  1. 编写一个xxxProperties,并使用@ConfigurationProperties来绑定到全局配置文件。
  2. 编写一个方法,该方法可以根据全局配置文件所配置的属性值来完成某些功能。
  3. 编写一个自动配置类(重点),在内部调用2编写的方法,并使用@Bean注解加入到容器中。想要让自动配置类生效,之前的博客记录过自动配置的原理,需要帮我们编写的自动配置类放到项目下的META-INF/spring.factories目录下,类似
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
你自己编写的自动配置类的全限定类名,\

我们就来编写个简单的功能,HelloProperties:

@ConfigurationProperties(prefix = "leslie.hello") //绑定到配置文件中
public class HelloProperties {

    private String prefix;
    private String suffix;

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
}

编写一个方法,用于返回配置文件中所配置的属性:

public class HelloService {

    HelloProperties helloProperties;

    public HelloProperties getHelloProperties() {
        return helloProperties;
    }

    public void setHelloProperties(HelloProperties helloProperties) {
        this.helloProperties = helloProperties;
    }

    public String sayHellAtguigu(String name){
        return helloProperties.getPrefix()+"-" +name + helloProperties.getSuffix(); //调用该方法可以返回字符串
    }
}

之前的做完了,接下来我们需要让编写的HelloService类生效,我们编写一个自动配置类

@Configuration
@ConditionalOnWebApplication //web应用才生效
@EnableConfigurationProperties(HelloProperties.class) //让Helloproperties生效
public class HelloServiceAutoConfiguration {

    @Autowired
    HelloProperties helloProperties;
    
    //将HelloService注册到容器中
    @Bean
    public HelloService helloService(){
        HelloService service = new HelloService();
        service.setHelloProperties(helloProperties);
        return service;
    }
}

最后再把HelloServiceAutoConfiguration配置到META-INF/spring.factories即可:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.leslie.starter.HelloServiceAutoConfiguration,\

之后在编写一个Controller来测试一下既可,这里略过。

记得有点杂乱,但还是很感谢你们的观看🙏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章