如何创建一个实用的SpringBoot自定义Starter项目

一、SpringBoot starter机制

SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进 starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动 相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自 动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应 用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

二、为什么要自定义starter

在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定 的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一 遍,麻烦至极。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候 只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽。

三、自定义starter的命名规则

SpringBoot提供的starter以 spring-boot-starter-xxx 的方式命名的。官方建议自定义的starter 使用 xxx-spring-boot-starter 命名规则。以区分SpringBoot生态提供的starter

四、开发自定义starter的步骤:

  • 1.新建Maven项目,在pom.xml中导入所需要的依赖

  • 2.创建xxProperties配置类,写好配置项和默认的配置值,指明配置项前缀,用来读取properties的配置信息

  • 3.创建xxService服务类,利用读取的到的资源进行业务操作,所有需要注入xxProperties的对象,通过构造器注入

  • 4.创建xxServiceAutoConfiguration自动装配类,使用@Configuration和@Bean来进行自动装配

  • 5.在resources中加入spring.factories 配置,指定Starter的自动装配类

五、starter开发示例

下面由我来示范如何开发starter,我将会创建一个文件上传的starter,利用到了org.springframework.web.multipart.MultipartFilecom.alibaba.fastjson.JSON

1…新建Maven项目,在pom.xml中导入所需要的依赖

<?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.sakura</groupId>
    <artifactId>upload-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--加入上传的配置依赖,不需要上传可去除-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>

        <!--JSON的依赖:不需要JSON可去除-->
        <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.7</version>
		</dependency>

        <!--自动配置的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

        <!--配置处理的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.2.2.RELEASE</version>
            <optional>true</optional>
        </dependency>



    </dependencies>

</project>

2.创建xxProperties配置类,写好配置项和默认的配置值,指明配置项前缀,用来读取properties的配置信息

package com.sakura.upload;

import org.springframework.boot.context.properties.ConfigurationProperties;
/**
 * 配置类
 */
@ConfigurationProperties(prefix = "spring.upload")//配置项前缀
public class UploadProperties {

    private String path;//配置项,此处用于指定文件要上传的地址

    private String url;//配置项,此处用于指定文件可以被访问的页面路径

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

3.创建xxService服务类,利用读取的到的资源进行业务操作,所有需要注入xxProperties的对象,通过构造器注入

package com.sakura.upload;

import com.alibaba.fastjson.JSON;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
 * 服务类
 */
public class UploadService {

    private UploadProperties uploadProperties;

    public UploadService(){

    }
    public UploadService(UploadProperties uploadProperties){
        this.uploadProperties=uploadProperties;
    }

    /**
     * 单文件上传
     * @param file
     * @return	字符串,文件的访问路径
     */
    public String uploadFile(MultipartFile file){
        if(!file.isEmpty()){
            String name = file.getOriginalFilename();
            String end = name.substring(name.lastIndexOf("."));
            String start = UUID.randomUUID().toString();
            File files=new File(uploadProperties.getPath()+start+end);
            try {
                file.transferTo(files);
                return uploadProperties.getUrl()+start+end;
            }catch (Exception e){
                e.printStackTrace();
            }

        }
        return null;
    }


    /**
     * 多文件上传
     * @param files
     * @return	json格式的字符串,文件的访问路径
     */
    public String uploadFiles2Json(MultipartFile[] files){
        if(files.length>0){
            List<String> list=new ArrayList<>();
            for (MultipartFile file:files) {
                if(!file.isEmpty()){
                    String name = file.getOriginalFilename();
                    String end = name.substring(name.lastIndexOf("."));
                    String start = UUID.randomUUID().toString();
                    File newFile=new File(uploadProperties.getPath()+start+end);
                    try {
                        file.transferTo(newFile);
                        list.add(start+end);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
            String string = JSON.toJSONString(list);
            return string;
        }
        return null;
    }

}

4.创建xxServiceAutoConfiguration自动装配类,使用@Configuration和@Bean来进行自动装配

package com.lihui.upload;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 自动装配类
 */
@Configuration
@EnableConfigurationProperties(UploadProperties.class)
@ConditionalOnClass(UploadService.class)
public class UploadServiceAutoConfiguration {


    @Autowired
    private UploadProperties uploadProperties;

    @Bean
    public UploadService uploadService(){
        return new UploadService(uploadProperties);
    }

}
   @ConditionalOnClass:当类路径classpath下有指定的类的情况下进行自动配置
   
   @ConditionalOnMissingBean:当容器(Spring Context)中没有指定Bean的情况下进行自动配置
   
   @ConditionalOnProperty(prefix = “example.service”, value = “enabled”,
   matchIfMissing =
   true),当配置文件中example.service.enabled=true时进行自动配置,如果没有设置此值就默认使用matchIfMissing对应的值
   
   @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
   
   @ConditionalOnBean:当容器(Spring Context)中有指定的Bean的条件下
   
   @ConditionalOnMissingClass:当类路径下没有指定的类的条件下
   
   @ConditionalOnExpression:基于SpEL表达式作为判断条件
   
   @ConditionalOnJava:基于JVM版本作为判断条件
   
   @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
   
   @ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
   
   @ConditionalOnWebApplication:当前项目是Web项目的条件下
   
   @ConditionalOnResource:类路径下是否有指定的资源
   
   @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean

5.在resources中加入spring.factories 配置,指定Starter的自动装配类
在这里插入图片描述

注意:META-INF是自己手动创建的目录,spring.factories文件位于resources/META-INF目录下,spring.factories也是手动创建的文件,在该文件中配置自己的自动配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.sakura.upload.UploadServiceAutoConfiguration

org.springframework.boot.autoconfigure.EnableAutoConfiguration后面的类名说明了自动装配类,如果有多个 ,则用逗号分开;
使用者应用(SpringBoot)在启动的时候,会通过org.springframework.core.io.support.SpringFactoriesLoader读取classpath下每个Starter的spring.factories文件,加载自动装配类进行Bean的自动装配;

六、使用自定义starter项目

步骤:
  1. maven install安装至本地仓库
  2. 在Spring Boot工程中引入依赖
  3. 配置Spring Boot工程中的application.properties

到这里,starter项目已经创建完毕,如果想要使用,可以将此starter项目maven install进行打包,这样就可以去使用了
在这里插入图片描述
项目想要使用自定义的starter,需要导入依赖,依赖就是starter项目pom.xml中这个位置的代码,如图所示:
在这里插入图片描述

<!--自定义starter项目依赖-->
        <dependency>
            <groupId>com.sakura</groupId>
            <artifactId>upload-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

依赖导入之后就可以去配置 application.properties
在这里插入图片描述
到这里,你就可以去使用自定义的starter项目了

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值