• SpringBoot自定义starter及自动配置


    SpringBoot的核心就是自动配置,而支持自动配置的是一个个starter项目。除了官方已有的starter,用户自己也可以根据规则自定义自己的starter项目。

    自定义starter条件

    自动化配置需满足以下条件:

    • 根据条件检查classpath下对应的类,也就是说需要提供对应可检查的类;
    • 当满足条件时能够生成定义的Bean,并注册到容器中去;
    • 能够自动配置项目所需要的配置;

    自定义spring boot starter

    这里通过maven项目管理工具进行starter的创建。首先我们需要创建一个简单的maven项目。这里我们以集成某短信服务为例,来创建一个项目。

    创建maven项目

    创建一个简单的maven项目,具体步骤省略。可通过intellj idea等IDE进行创建,也可通过maven命令进行创建。

    目录结构如下:

    .
    ├── pom.xml
    ├── spring-boot-starter-msg.iml
    └── src
        ├── main
        └── test
    

    在pom.xml中引入SpringBoot自动化配置依赖spring-boot-autoconfigure:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>2.1.5.RELEASE</version>
    </dependency>
    

    定义Service服务类

    定义Service服务类,有两个作用,一个为引入的项目本省的功能性服务,另外一个用来springboot自动配置时的判断依据。

    这里定义一个MsgService的类。

    package com.secbro2.msg;
    
    import com.secbro2.utils.HttpClientUtils;
    
    public class MsgService {
    
    	/**
    	 * 访问发送短信的url地址
    	 */
    	private String url;
    
    	/**
    	 * 短信服务商提供的请求keyId
    	 */
    	private String accessKeyId;
    
    	/**
    	 * 短信服务商提供的KeySecret
    	 */
    	private String accessKeySecret;
    
    	public MsgService(String url, String accessKeyId, String accessKeySecret) {
    		this.url = url;
    		this.accessKeyId = accessKeyId;
    		this.accessKeySecret = accessKeySecret;
    	}
    
    	public int sendMsg(String msg) {
    		// 调用http服务并发送消息,返回结果
    		return HttpClientUtils.sendMsg(url, accessKeyId, accessKeySecret, msg);
    	}
    
    	// 省略getter/setter方法
    }
    
    

    其中MsgService用到了一个工具类HttpClientUtils。在HttpClientUtils中只简单打印了请求的参数信息。

    package com.secbro2.utils;
    
    public class HttpClientUtils {
    
    	public static int sendMsg(String url, String accessKeyId, String accessKeySecret, String msg) {
    		//TODO 调用指定url进行请求的业务逻辑
    		System.out.println("Http请求,url=" + url + ";accessKeyId=" + accessKeyId + ";accessKeySecret=" + accessKeySecret + ";msg=" + msg);
    		return 0;
    	}
    }
    

    定义配置类

    定义MsgProperties配置类,用于封装application.properties或application.yml中的基础配置。这里关于短信发送的配置前缀统一采用msg。

    @ConfigurationProperties(prefix = "msg")
    public class MsgProperties {
    
    	/**
    	 * 访问发送短信的url地址
    	 */
    	private String url;
    
    	/**
    	 * 短信服务商提供的请求keyId
    	 */
    	private String accessKeyId;
    
    	/**
    	 * 短信服务商提供的KeySecret
    	 */
    	private String accessKeySecret;
    	
    	// 其他参数定义
    	// 省略getter/setter方法
    
    }
    

    通过@ConfigurationProperties注解来进行对应的属性的装配。

    创建自动化配置类

    自动配置类就是一个普通的java类,通过不同的注解来对其赋予不同的功能。其中最核心的当然是@Configuration注解。

    @Configuration
    @ConditionalOnClass(MsgService.class)
    @EnableConfigurationProperties(MsgProperties.class)
    public class MsgAutoConfiguration {
    
    	/**
    	 * 注入属性配置类
    	 */
    	@Resource
    	private MsgProperties msgProperties;
    
    	@Bean
    	@ConditionalOnMissingBean(MsgService.class)
    	@ConditionalOnProperty(prefix = "msg", value = "enabled", havingValue = "true")
    	public MsgService msgService() {
    		MsgService msgService = new MsgService(msgProperties.getUrl(), msgProperties.getAccessKeyId(),
    				msgProperties.getAccessKeySecret());
    		// 如果提供了其他set方法,在此也可以调用对应方法对其进行相应的设置或初始化。
    		return msgService;
    	}
    }
    

    MsgAutoConfiguration类上的注解,@Configuration用来声明该类为一个配置类;@ConditionalOnClass注解说明只有当MsgService类存在于classpath中时才会进行相应的实例化;@EnableConfigurationProperties将application.properties中对应的属性配置设置于MsgProperties对象中;

    msgService方法上的注解,@Bean表明该方法实例化的对象会被加载到容器当中;@ConditionalOnMissingBean指明当容器中不存在MsgService的对象时再进行实例化;@ConditionalOnProperty指定了配置文件中msg.enabled=true时才进行相应的实例化。

    添加spring.factories

    当所有的基础代码和自动配置类都准备完成,就需要对其进行注册。也就是我们熟悉的META-INF/spring.factories配置文件了。当然,这个需要在自己的项目中进行创建。

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.secbro2.msg.MsgAutoConfiguration
    

    在spring.factories配置文件中注册MsgAutoConfiguration类。如果有多个自动配置类,用逗号分隔换行即可。

    至此,一个基于Spring Boot的自动配置starter便完成了。使用“maven:install”将其打包到本地maven仓库或上传至私服。其他项目便可以通过maven依赖使用。

    starter项目使用

    在其他项目中,通过以下依赖引入该依赖。

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

    然后在当前项目的application.properties中配置对应的参数:

    msg.enabled=true
    msg.url=127.0.0.1
    msg.accessKeyId=10001
    msg.accessKeySecret=afelwjfwfwef
    

    比如其他项目同样是Spring Boot项目,则可定义一个简单的Controller来进行测试。

    @RestController
    public class HelloWorldController {
    
    	@Resource
    	private MsgService msgService;
    
    	@RequestMapping("/sendMsg")
    	public String sendMsg(){
    		msgService.sendMsg("测试消息");
    		return "";
    	}
    }
    

    当通过浏览器访问:http://localhost:8080/sendMsg时,便会打印出如下日志:

    Http请求,url=127.0.0.1;accessKeyId=10001;accessKeySecret=afelwjfwfwef;msg=测试消息
    

    说明MsgService对象被自动配置,并且测试通过。

    而针对短信发送这样的starter,可以进行进一步拓展,实现短信发送的各种基础功能,而当其他项目需要时只用引入对应的依赖,并配置具体的参数即可马上使用,是不是非常方便?

    总结下Starter的工作流程:

    • Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包;
    • 根据spring.factories配置加载AutoConfiguration类;
    • 根据@Conditional注解的条件,进行自动配置并将Bean注入Spring容器。


    程序新视界:精彩和成长都不容错过
    ![程序新视界-微信公众号](https://img2018.cnblogs.com/blog/1742867/201910/1742867-20191013111755842-2090947098.png)
  • 相关阅读:
    cad三维多断线的合并
    将list中的每个元素转换成str
    ndarray格式的点云数组转变为open3d.open3d.geometry.PointCloud
    汉字读音积累
    python文件内的函数调用
    numpy.dot()函数
    父亲啊,儿子是您永远的牵挂
    2008江西高考0分作文
    记忆一个朋友
    暴风雨前的天空
  • 原文地址:https://www.cnblogs.com/secbro/p/11810105.html
Copyright © 2020-2023  润新知