我们知道SpringBoot Starter也就是启动器。是SpringBoot组件化的一大优点。基于这个思想,基于这个思想SpringBoot 才变得非常强大,官方给我们提供很多开箱即用的启动器。
Spring Boot Starter 是 Spring Boot 的一个重要特性,它有以下优点:
依赖管理:Starter 自动处理项目的依赖关系,使得开发者无需手动添加和管理每个依赖。
自动配置:Starter 提供了一种自动配置的方式,可以根据你的 classpath 和你定义的属性自动配置 Spring 应用。
简化开发:通过提供各种服务的 Starter(如数据库、安全、缓存等),极大地简化了开发过程。
减少样板代码:由于 Starter 的自动配置和依赖管理,开发者可以专注于业务逻辑,而不是配置和基础设施代码。
快速原型开发:使用 Starter 可以快速创建可运行的原型。
易于理解和使用:Spring Boot Starter 的设计目标之一就是让非专业的开发者也能快速上手。
社区支持:除了官方提供的 Starter,还有大量的社区提供的 Starter,可以满足各种特定需求。
我现在手把手教大家如何封装自己的starter 做自己的springboot组件,当然你也可以发布自己的starter 到maven中央仓库供大家使用
我们以WebMvcAutoConfiguration这个自动加载为例
自动配置类要能加载,有一个要求,源码分析结果是,需要在\META-INF\spring.factories中做如下配置
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
这样SpringBoot在启动完成时候,会找到我们引入,的starter 找到\META-INF\spring.factories
属性文件,找到需要自动加载配置的类路径,然后帮我们自动注入到Spring IOC 容器,我们在项目中就可以直接使用了。
这里实现自动加载还要依赖一些注解如:
@Configuration // 指定这个类是个配置类
@ConditionalOnXXX // 在指定条件成立的情况下自动配置类生效
@AutoConfigureOrder //配置类顺序
@AutoConfigureAfter // 在哪个配置类之后
@Bean //给容器中添加组件
@ConfigurationProperties //结合相关的XXXProperties类 来绑定相关的配置
@EnableConfigurationProperties // 让XXXProperties加入到容器中,别人就可以自动装配
剖析了SpringBoot 官方的starter 我们自定义自己的starter,(我们仿照着写)
如果自定义属性文件中,需要IDEA智能提示需要引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
这里我以自己封装总结我工作以来总结项目封装的一个SpringBoot starter为例
<dependency>
<groupId>cn.soboys</groupId>
<artifactId>rest-api-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
就是我自己封装的start。已经发布中央仓库。
目前更新版本1.3.0 功能如下
rest-api-spring-boot-starter
仓库地址
自定义配置属性文件
rest-api:
enabled: false
logging:
path: ./logs
i18n:
# 若前端无header传参则返回中文信息
i18n-header: Lang
default-lang: cn
message:
# admin
internal_server_error:
en: Internal Server Error
cn: 系统错误
not_found:
en: Not Found
cn: 请求资源不存在
定义属性配置类
package cn.soboys.restapispringbootstarter.i18n;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
import java.util.Optional;
/**
@author 公众号 程序员三时
@version 1.0
@date 2023/6/26 11:55
@webSite https://github.com/coder-amiao
/
//@PropertySource(value = "classpath:i18n.yaml", factory = YamlPropertySourceFactory.class)
@Configuration
@ConfigurationProperties(prefix = "rest-api.i18n")
@Data
public class I18NMessage {
/*
private String i18nHeader = "Lang";
/**
/**
}
定义BeanAutoConfiguration自动加载配置类
package cn.soboys.restapispringbootstarter.config;
import cn.soboys.restapispringbootstarter.ApplicationRunner;
import cn.soboys.restapispringbootstarter.ExceptionHandler;
import cn.soboys.restapispringbootstarter.ResultHandler;
import cn.soboys.restapispringbootstarter.aop.LimitAspect;
import cn.soboys.restapispringbootstarter.i18n.I18NMessage;
import cn.soboys.restapispringbootstarter.utils.RedisTempUtil;
import cn.soboys.restapispringbootstarter.utils.RestFulTemp;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.List;
/**
@author 公众号 程序员三时
@version 1.0
@date 2023/6/27 11:36
@webSite https://github.com/coder-amiao
*/
@Configuration
@ConditionalOnProperty(name = "rest-api.enabled", havingValue = "true")
public class BeanAutoConfiguration {
@Bean
public I18NMessage i18NMessage() {
return new I18NMessage();
}
@Bean
public ResultHandler resultHandler() {
return new ResultHandler();
}
@Bean
public ExceptionHandler exceptionHandler() {
return new ExceptionHandler();
}
@Bean
public StartupApplicationListener startupApplicationListener() {
return new StartupApplicationListener();
}
@Bean
public RestApiProperties restApiProperties() {
return new RestApiProperties();
}
@Bean
public RestApiProperties.LoggingProperties loggingProperties(RestApiProperties restApiProperties) {
return restApiProperties.new LoggingProperties();
}
@Bean
public ApplicationRunner applicationRunner() {
return new ApplicationRunner();
}
/**
restTemplate 自动注入
/
@Configuration
@ConditionalOnProperty(name = "rest-api.enabled", havingValue = "true")
class RestTemplateConfig {
/*
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
// 处理请求中文乱码问题
List
for (HttpMessageConverter> messageConverter : messageConverters) {
if (messageConverter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) messageConverter).setDefaultCharset(thirdRequest);
}
if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
((MappingJackson2HttpMessageConverter) messageConverter).setDefaultCharset(thirdRequest);
}
if (messageConverter instanceof AllEncompassingFormHttpMessageConverter) {
((AllEncompassingFormHttpMessageConverter) messageConverter).setCharset(thirdRequest);
}
}
return restTemplate;
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000);
factory.setReadTimeout(5000);
return factory;
}
@Bean
public RestFulTemp restFulTemp() {
return new RestFulTemp();
}
}
}
自动装配
在项目
spring.factories
配置自己加载配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration,\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration.RestTemplateConfig,\
cn.soboys.restapispringbootstarter.utils.RedisTempUtil\
扩展思考,我们可以看到SpringBoot官方stater 很多启用都类似
@Enablexxx
注解这个怎么实现。我的
rest-api-spring-boot-starter
1.3.0已经实现不需要在application.properties配置一行 直接在启动类或者配置类使用EnableRestFullApi
就可以使用全部功能
完善文档使用可以看我
SpringBoot定义优雅全局统一Restful API 响应框架完结撒花篇封装starter组件
这篇文章
到此自己定义starter就写完了 接下来就是打包,发布到maven中央仓库。
我会在 下一篇文章继续分享
留下你的思考,关注公众 程序员三时
持续输出优质内容 希望给你带来一点启发和帮助
手机扫一扫
移动阅读更方便
你可能感兴趣的文章