springboot 通用脚手架搭建(maven archetype)
说明
为了不在启动新项目的时候不重复造轮子,采用maven archetype 制作一个通用的springboot脚手架,一件生成需要用到的springboot 技术栈
技术方案
- springboot
- mybatis-plus
- java8
- redis
- mysql
- logback
- jwt token
引入依赖
springboot
org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import
jwt token
io.jsonwebtoken jjwt ${jjwt.version}
fastjson json工具
com.alibaba fastjson ${fastjson.version}
api接口文档工具
com.github.xiaoymin knife4j-spring-boot-starter ${knife4j.version}
mysql 数据库
mysql mysql-connector-java ${mysql.version}
mybatis-plus
com.baomidou mybatis-plus-boot-starter ${mybatis-plus.version}
lombok 自动生成set/get方法工具
org.projectlombok lombok ${lombok.version}
通用工具类
org.apache.commons commons-pool2 ${commons-pool2.version}
http请求工具
org.apache.httpcomponents httpclient ${httpclient.version}
springboot web
org.springframework.boot spring-boot-starter-web
springboot freemark
org.springframework.boot spring-boot-starter-freemarker
springboot test 测试用具
org.springframework.boot spring-boot-starter-test
springboot aop
org.springframework.boot spring-boot-starter-aop
springboot redis
org.springframework.boot spring-boot-starter-data-redis
springboot validation 参数验证
org.springframework.boot spring-boot-starter-validation
springboot retry 重试机制
org.springframework.retry spring-retry
项目模块
根目录pom.xml
4.0.0 com.cap custom-archetype-project pom 1.0-SNAPSHOT application-starter common-service 8 8 UTF-8 2.3.12.RELEASE 3.0.2 8.0.20 3.5.2 1.2.60 0.7.0 1.18.20 2.11.1 4.5.13 org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import io.jsonwebtoken jjwt ${jjwt.version} com.alibaba fastjson ${fastjson.version} com.github.xiaoymin knife4j-spring-boot-starter ${knife4j.version} mysql mysql-connector-java ${mysql.version} com.baomidou mybatis-plus-boot-starter ${mybatis-plus.version} com.baomidou mybatis-plus-generator ${mybatis-plus.version} org.projectlombok lombok ${lombok.version} org.apache.commons commons-pool2 ${commons-pool2.version} org.apache.httpcomponents httpclient ${httpclient.version} com.cap common-service ${version} org.apache.maven.plugins maven-archetype-plugin 3.0.1
启动模块 application-starter
一般存放启动类和配置类
启动类
@SpringBootApplication
@EnableScheduling
@EnableRetry
@MapperScan({"com.cap.mapper"})
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}
}
redis 配置
@Configuration
public class RedisConfig {@Beanpublic RedisCache jlbRedisCache(RedisConnectionFactory redisConnectionFactory) {return new RedisCache(redisTemplate(redisConnectionFactory));}@Bean@ConditionalOnMissingBean(RedisTemplate.class)public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);template.afterPropertiesSet();return template;}@Beanpublic RedisDistributeLock distributeLock(RedisConnectionFactory redisConnectionFactory) {return new RedisDistributeLock(redisTemplate(redisConnectionFactory));}@Beanpublic RedisDistributeBlockingLock distributeBlockingLock(RedisConnectionFactory redisConnectionFactory) {return new RedisDistributeBlockingLock(redisTemplate(redisConnectionFactory));}
}
mybatis-plus 配置
@Configuration
public class MybatisPlusConfig {@Beanpublic PaginationInnerInterceptor paginationInterceptor() {return new PaginationInnerInterceptor();}
}
api接口文档配置
@Configuration
@EnableOpenApi
public class Knife4jConfig {@Beanpublic Docket docket(){List requestParameters = new ArrayList<>();requestParameters.add(new RequestParameterBuilder().name("token").description("token").required(false).in(ParameterType.HEADER).build());return new Docket(DocumentationType.SWAGGER_2).host("http://127.0.0.1:8080/cap").apiInfo(apiInfo()).globalRequestParameters(requestParameters).groupName("分组名称").select().apis(RequestHandlerSelectors.basePackage("com.cap")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("文档标题").description("文档描述").contact(new Contact("作者名称", null, "邮箱")).version("文档版本").build();}}
公共模块 common-service
通用工具类、异常补货、通用枚举等
异常处理
自定义异常类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApplicationException extends RuntimeException implements Serializable {private Integer code;private String message;public ApplicationException(BaseErrorCodeEnum errorCodeEnum) {super();this.code = errorCodeEnum.getCode();this.message = errorCodeEnum.getMessage();}public ApplicationException(BaseErrorCodeEnum errorCodeEnum, String message) {super();this.code = errorCodeEnum.getCode();this.message = message;}@Overridepublic String getMessage() {return message;}
}
统一异常补货
@ControllerAdvice
public class ApplicationExceptionAdvice {@ExceptionHandler(ApplicationException.class)@ResponseStatus(value = HttpStatus.OK)@ResponseBodypublic Response applicationException(ApplicationException e){return Response.failed(e.getCode(), e.getMessage());}
}
参数校验异常补货
@ControllerAdvice
@Slf4j
public class ParamsValidateExceptionAdvice {@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(value = HttpStatus.OK)@ResponseBodypublic Response methodArgumentNotValidException(MethodArgumentNotValidException e){String message = null;for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {message = fieldError.getDefaultMessage();if (StringUtils.isNotEmpty(message)) {break;}}return Response.failed(HttpStatus.BAD_REQUEST.value(), message);}@ExceptionHandler(ConstraintViolationException.class)@ResponseStatus(value = HttpStatus.OK)@ResponseBodypublic Response constraintViolationException(ConstraintViolationException e){String message = null;for (ConstraintViolation> constraintViolation : e.getConstraintViolations()) {message = constraintViolation.getMessage();if (StringUtils.isNotEmpty(message)) {break;}}return Response.failed(HttpStatus.BAD_REQUEST.value(), e.getMessage());}@ExceptionHandler(HttpMessageNotReadableException.class)@ResponseStatus(value = HttpStatus.OK)@ResponseBodypublic Response httpMessageNotReadableException(HttpMessageNotReadableException e){return Response.failed(HttpStatus.BAD_REQUEST.value(), ResultCodeEnum.PARAMS_FAILED.getMessage());}
}
通用枚举
public interface BaseErrorCodeEnum {Integer getCode();String getMessage();
}
@AllArgsConstructor
@Getter
public enum ResultCodeEnum implements BaseErrorCodeEnum {SUCCESS(0, "操作成功"),PARAMS_FAILED(400, "请求参数异常"),UNAUTHORIZED(401, "没有权限访问"),NOT_FOUND(404, "数据找不到"),FAILED(500, "操作失败,请稍后再试"),;private Integer code;private String message;}
通用vo
接口统一响应对象
@AllArgsConstructor
@NoArgsConstructor
public class Response {public Integer code;private String message;private T data;public static Response success(Object data){return new Response(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage(), data);}public static Response success(){return new Response(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage(), null);}public static Response failed(Integer code, String message){return new Response(code, message, null);}public static Response failed(BaseErrorCodeEnum errorCodeEnum){return new Response(errorCodeEnum.getCode(), errorCodeEnum.getMessage(), null);}public static Response failed(BaseErrorCodeEnum errorCodeEnum, String message){return new Response(errorCodeEnum.getCode(), message, null);}
}
工具类
代码自动生成
public class GeneratorUtil {private final static List tableNames = Arrays.asList("osm_config");private final static List tablePrefix = Arrays.asList("osm_");private final static String parentPackageName = "com.cap";private final static String moduleName = "com.cap";public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://47.98.215.38:3006/ybf-patient?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2b8&useSSL=false", "root", "C_x123456").globalConfig(config -> config.author("jzz").commentDate("yyyy-MM-dd hh:mm").enableSwagger().dateType(DateType.ONLY_DATE).outputDir(System.getProperty("user.dir") + "/src/main/java/" + parentPackageName + "/")).packageConfig(config -> config.parent(parentPackageName).moduleName(moduleName)).strategyConfig(config -> {config.enableCapitalMode().addInclude(tableNames).addTablePrefix(tablePrefix).entityBuilder().superClass(BaseEntity.class).disableSerialVersionUID().enableLombok().enableTableFieldAnnotation().addSuperEntityColumns("id", "gmt_create", "gmt_modified", "deleted").idType(IdType.AUTO).formatFileName("%sEntity").controllerBuilder().enableRestStyle().formatFileName("%sController").serviceBuilder().formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImp").mapperBuilder().enableMapperAnnotation().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper");}).templateEngine(new FreemarkerTemplateEngine()).execute();}
}
jwt-token工具类
@Slf4j
public class JwtUtil {private static final String SECRET = "recycle&%[%}d#f[$35$%-hdsk#!@$]";private static final String JWT_SEPARATOR = "Bearer ";private static final Date EXPIRE = new Date(System.currentTimeMillis() + 365L * 24L * 60L * 60L * 1000L);private static final String JWT_ID = UUID.randomUUID().toString();/*** 生成jwt* @param claims* @return*/public static String buildJwt(Map claims) {Map header = new HashMap<>();header.put("typ", "JWT");return JWT_SEPARATOR + Jwts.builder().setHeader(header).setClaims(claims).setId(JWT_ID).setIssuedAt(new Date()).setExpiration(EXPIRE).signWith(SignatureAlgorithm.HS512, SECRET).compact();}/*** 获取Claim* @param token* @return*/public static String getClaim(String token){token = StringUtils.substringAfter(token, JWT_SEPARATOR);try {Object body = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();return JSONObject.toJSONString(body);}catch (Exception e) {return null;}}/*** 校验token* @param token* @return*/public static Boolean checkJwt(String token){return Objects.nonNull(token);}
}
archetype生成
- 项目跟目录下执行
mvn archetype:create-from-project
- 执行成功后在项目目录会出现一下文件

- 进入target/generated-sources/archetype/目录下按顺序执行
mvn install
mvn archetype:crawl
- 执行成功后在maven仓库会出现archtype-catalog.xml文件

- 文件内容

- 打开idea新建项目选择maven archetype

目录选择:默认本地 - 点击添加按钮

输入archtype-catalog.xml文件对应的信息,输入完成之后设置新项目的包名等信息,点击创建即可完毕 - 以后在创建新项目,选择自己的maven archetype就能创建通用项目模版
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
