什么是Boot
过去只是用人家的xxx-spring-boot-starter
,用着是挺爽的,但随着学习和工作,发现不管是流行的开源产品还是公司内部总会存在一些自己封装的starter
,刚开始我也是很不解,一直觉得原本的就是最好的,根本不需要我们改什么,直到我学着去自己写starter
,才发觉脚手架的意义就在这啊,这就是boot
啊!
不多废话了,接下来从开源项目yudao-cloud说起怎么在开源框架的基础上封装自己的starter
。
尝试自己写starter
我们就从yudao-spring-boot-starter-job
开始做一个属于自己的starter吧!
前提说明
SpringBoot
基础的就不用多提了,需要注意的是不同版本会有一些差异,SpringBoot2.7之后自动配置类差异。
依赖
主要就是spring
核心依赖和xxl-job
的依赖,第一个依赖是自己写的工具类,可以不用在意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <?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> <parent> <groupId>cn.wnhyang.cloud</groupId> <artifactId>okay-framework</artifactId> <version>1.0-SNAPSHOT</version> </parent>
<artifactId>okay-spring-boot-starter-job</artifactId> <packaging>jar</packaging>
<dependencies> <dependency> <groupId>cn.wnhyang.cloud</groupId> <artifactId>okay-common</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <optional>true</optional> </dependency>
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> </dependency>
<dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <scope>provided</scope> </dependency>
</dependencies>
</project>
|
配置类
主要配置两项内容
异步线程配置
Spring
自带其自动配置,开启便可
1 2 3 4
| @AutoConfiguration @EnableAsync public class AsyncAutoConfiguration { }
|
XXL-JOB配置
xxl-job
具体配置可参考其官网,这里做了简单的封装。
首先是属性配置类,将原先xxl-job
的配置项进行分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| @ConfigurationProperties("xxl.job") @Validated @Data public class XxlJobProperties {
private Boolean enabled = true;
private String accessToken;
@NotNull(message = "控制器配置不能为空") private AdminProperties admin;
@NotNull(message = "执行器配置不能为空") private ExecutorProperties executor;
@Data @Valid public static class AdminProperties {
@NotEmpty(message = "调度器地址不能为空") private String addresses;
}
@Data @Valid public static class ExecutorProperties {
private static final Integer PORT_DEFAULT = -1;
private static final Integer LOG_RETENTION_DAYS_DEFAULT = 30;
@NotEmpty(message = "应用名不能为空") private String appName;
private String ip;
private Integer port = PORT_DEFAULT;
@NotEmpty(message = "日志地址不能为空") private String logPath;
private Integer logRetentionDays = LOG_RETENTION_DAYS_DEFAULT;
}
}
|
具体配置同于官网
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @AutoConfiguration @ConditionalOnClass(XxlJobSpringExecutor.class) @ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true", matchIfMissing = true) @EnableConfigurationProperties({XxlJobProperties.class}) @EnableScheduling @Slf4j public class XxlJobAutoConfiguration {
@Bean @ConditionalOnMissingBean public XxlJobExecutor xxlJobExecutor(XxlJobProperties properties) { log.info("[xxlJobExecutor][初始化 XXL-Job 执行器的配置]"); XxlJobProperties.AdminProperties admin = properties.getAdmin(); XxlJobProperties.ExecutorProperties executor = properties.getExecutor();
XxlJobExecutor xxlJobExecutor = new XxlJobSpringExecutor(); xxlJobExecutor.setIp(executor.getIp()); xxlJobExecutor.setPort(executor.getPort()); xxlJobExecutor.setAppname(executor.getAppName()); xxlJobExecutor.setLogPath(executor.getLogPath()); xxlJobExecutor.setLogRetentionDays(executor.getLogRetentionDays()); xxlJobExecutor.setAdminAddresses(admin.getAddresses()); xxlJobExecutor.setAccessToken(properties.getAccessToken()); return xxlJobExecutor; }
}
|
从这里的配置来看真的和xxl-job
官网配置几乎一样,相比来说,我理解的好处就是,可以默认设置一些配置属性,当然这个仅仅是对于开源项目封装最简单的一个例子,另外有些公司里的boot
深入源码就不是这么简单的了。
自动化配置
项目resources/META-INF/spring
下org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件添加上面的Configuration
类就好
1 2 3
| cn.wnhyang.okay.framework.job.config.XxlJobAutoConfiguration cn.wnhyang.okay.framework.job.config.AsyncAutoConfiguration
|
使用
依赖
添加自己的boot
1 2 3 4
| <dependency> <groupId>cn.wnhyang.cloud</groupId> <artifactId>okay-spring-boot-starter-job</artifactId> </dependency>
|
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| xxl.job.enabled=false
xxl.job.admin.addresses=http://123.60.165.53:8083/xxl-job-admin
xxl.job.accessToken=default_token
xxl.job.executor.appname=${spring.application.name}
xxl.job.executor.ip=
xxl.job.executor.port=9997
xxl.job.executor.logpath=logs/xxl-job/jobhandler
xxl.job.executor.logretentiondays=30
spring.task.execution.thread-name-prefix=task- spring.task.execution.pool.core-size=8 spring.task.execution.pool.max-size=20 spring.task.execution.pool.keep-alive=60s spring.task.execution.pool.queue-capacity=200 spring.task.execution.pool.allow-core-thread-timeout=true spring.task.execution.shutdown.await-termination=true spring.task.execution.shutdown.await-termination-period=60
|
这样就可以愉快的玩耍了
总结
虽然只是一个简单的例子,还是可以看出来自己写starter
的意义的,目前我也是在学习开源项目的同时自己做一些简单的小项目玩,还觉得挺有意思的。