内容简介:目标:减少重复代码,提高开发效率,项目地址:可封装功能列表目前已经实现上面列表中的所有功能并开源
目标:减少重复代码,提高开发效率,项目地址: github.com/neatlife/jf…
欢迎star,欢迎pr(求star, 求star, 求star)
可封装功能列表
| E文 | 功能 | 目前作用 |
|---|---|---|
| controller | 控制器父类 | 简化控制器里的常见操作 |
| exception | 异常 | 统一全局业务异常操作 |
| handler | 异常拦截 | 全局异常拦截到日志里 |
| http | 请求响应实体 | 统一全局响应实体 |
| hystrix | hystrix事件拦截 | 熔断时发送报警邮件 |
| jpa | jpa非业务重复代码封装 | 自动给deleted_at, updated_at, created_at赋值 |
| json | 响应json数据的二次处理 | 自动格式化金额小数位数 |
| listener | spring boot框架事件 | 在框架启动时给util注入service实例 |
| logback | 自定义logback日志输出 | 将日志输出到elk的redis,方便elk统一进行日志处理 |
| model | 基础jpa实体 | 包含deleted_at, updated_at, created_at字段的实体 |
| redis | 自定义 redis 序列化和反序列化操作 | 使用GenericJackson2JsonRedisSerializer序列化redis值,提高可读性 |
| request | 自定请求数据的解析 | 处理json请求 |
| springfox | 自定义springfox文档解析 | ApiClass支持文档描述引用 |
| util | 常用 工具 收集 | 比如json, http请求等常用工具类 |
| validator | 请求参数自定义校验 | 检查参数长度 |
| apiversion | 支持不同的api的版本到不同的控制器逻辑 | 参考 MainController |
目前已经实现上面列表中的所有功能并开源
一些关键的点
json & http客户端的封装
json & http客户端经常使用,自行编写容易踩坑,所以直接拿dew框架的工具类进行了集成
需要同时发出多个http请求时可以使用parallelStream()技术,可显著减少请求总时长
List<String> paramList = ...
paramList.parallelStream().forEach(param -> {
http post with param
})
复制代码
经测试, 26个请求,使用parallelStream将请求总时间从23.803减少到1.731秒
MapperUtil工具类的封装
因为 java 里对象复制非常频繁,所以封装了MapperUtil, 虽然复制对象只需下面两行代码
Class1 class1 = new Class1(); BeanUtils.copyProperties(source, class1); 复制代码
但是由于非常频繁的类似代码,一个项目项目可能出现上千次这种复制,所以将上面两行代码合并成了一行
Class1 class1 = MapperUtil.to(source, class1); 复制代码
核心实现代码如下:
public static <SOURCE, TARGET> TARGET to(SOURCE source, Class<TARGET> targetClass) {
TARGET target = BeanUtils.instantiateClass(targetClass);
BeanUtils.copyProperties(source, target);
return target;
}
复制代码
虽然使用了反射技术,但经过测试无性能问题
elk日志
使用redis进行了日志中转,所以logstash需要从redis读取日志输出到elasticsearch
logstash从redis读取日志输出到elasticsearch的配置
input {
redis {
data_type => "list"
key => "logstash"
host => "127.0.0.1"
port => 6379
threads => 5
codec => "json"
}
}
filter {
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "logstash-%{type}-%{+YYYY.MM.dd}"
document_type => "%{type}"
workers => 1
template_overwrite => true
}
stdout{}
}
复制代码
因为elasticsearch里日志会越来越大,所以需要定时清理,定时清理elasticsearch数据
参考: www.jianshu.com/p/458421dac…
核心代码如下
#!/bin/bash
# filename:deleteEsData.sh
# 每天2点定时删除es中指定日期的数据
# crontab: 0 2 * * * sh /home/scripts/deleteEsData.sh >> /home/scripts/logs/deleteEsData.run.log 2>&1
# 如今天是2017-09-21 50天前是2017.08.02
# createdate: 20190921
today=`date +%Y-%m-%d`;
echo "今天是${today}"
# 不指定参数时,默认删除daynum天前以logs-开头的数据
daynum=51
# 当参数个数大于1时,提示参数错误
if [ $# -gt 1 ] ;then
echo "要么不传参数,要么只传1个参数!"
exit 101;
fi
# 当参数个数为1时,获取指定的参数
if [ $# == 1 ] ;then
daynum=$1
fi
esday=`date -d '-'"${daynum}"' day' +%Y.%m.%d`;
echo "${daynum}天前是${esday}"
curl -XDELETE http://127.0.0.1:9200/logs-${esday}
echo "${esday} 的log删除执行完成"
复制代码
全局业务异常
定义全局业务异常,方便进行全局业务异常的捕获和统一处理 ControllerExceptionHandler
核心处理逻辑如下:
@ExceptionHandler({BusinessRuntimeException.class})
@ResponseBody
public Response handlerBusinessException(BusinessRuntimeException ex) {
return new Response<Map>(HttpCode.SUCCESS.toString(), ex.getMessage(), Maps.newHashMap());
}
复制代码
这样的好处是方便对错误的返回数据进行格式化
利用框架事件,简化util
RedisUtil工具类需要RedisTemplate操作实例对象,如果在RedisUtil使用Autowired自动注入RedisTemplate,则需要RedisUtil也是Service,这将RedisUtil的调用变得复杂化了(使用前必须先注入RedisUtil以获取RedisTemplate对象) 利用框架事件,可在框架启动时,获取RedisTemplate对象,手动注入RedisUtil里
核心实现代码如下:
@Component
public class ApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
private final RedisTemplate redisTemplate;
private final JFrameworkConfig jFrameworkConfig;
@Autowired
public ApplicationStartedEventListener(RedisTemplate redisTemplate, JFrameworkConfig jFrameworkConfig) {
this.redisTemplate = redisTemplate;
this.jFrameworkConfig = jFrameworkConfig;
}
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
RedisUtil.setRedisTemplate(redisTemplate);
LockUtil.setRedisTemplate(redisTemplate);
DingTalkUtil.setDdUrl(jFrameworkConfig.getNotification().getDingTalkUrl());
}
}
复制代码
docker 镜像仓库选择
自行搭建镜像仓库不如使用免费稳定的来得高效可靠
可以直接使用了aliyun提供的免费 docker 镜像仓库
自动维护created_at, updated_at, deleted_at字段
采用了jpa的事件机制,在创建,修改,删除事件发生时自动进行维护
核心代码如下:
@PrePersist
public void touchCreated(BaseEntity target) {
target.setCreatedAt(DateUtil.currentSecond());
target.setUpdatedAt(DateUtil.currentSecond());
}
@PreUpdate
public void touchUpdate(BaseEntity target) {
target.setUpdatedAt(DateUtil.currentSecond());
}
@PreRemove
public void touchDeleted(BaseEntity target) {
target.setDeletedAt(DateUtil.currentSecond());
}
复制代码
ci/cd的选择
目前ci/cd工具选择非常多,但在生产里用得最多的应该是gitlab和jenkins
目前仍然采用jenkins作为ci/cd工具,gitlab的ci目前个人认为仍然不够成熟
代码质量检测
可以直接试用sonarkube的开放服务,无需自行搭建:
打包分发
一般框架会作为项目的基础依赖,那么能够非常方便的下载这个框架就非常重要了
目前nexus私服仍然是首选,可以使用docker搭建nexus私服:
version: "3"
services:
nexus:
image: sonatype/nexus3
environment:
- INSTALL4J_ADD_VM_PARAMS=-Xms512m -Xmx768m -XX:MaxDirectMemorySize=1g -Djava.util.prefs.userRoot=/nexus-data/javaprefs
volumes:
- ./nexus-data:/nexus-data
ports:
- "8081:8081"
复制代码
微服务
由于是微服务形式的部署,所以日志,配置都需要中心化,k8s也是标配
日志选经典的elk
配置中心选择apollo
部署平台可以选择k8s,或者k8s上的istio,目前使用k8s
微服务的k8s模版参考 应用: raw.githubusercontent.com/neatlife/jf… 网关: raw.githubusercontent.com/neatlife/jf…
核心区别是kind字段,网关是 DaemonSet 应用是 Deployment
项目参考
完成框架的封装必然少不了很多参考,即使这是个小框架
以下是参考列表
- github.com/kmtong/logb…
- github.com/looly/hutoo…
- github.com/gudaoxuri/d…
- github.com/gudaoxuri/d…
- github.com/xdd-organ/x…
- github.com/indrabasak/…
- github.com/ityouknow/s…
- github.com/WellJay/spr…
目前文章还在持续更新中,如果对框架开发感兴趣,可加作者微信探讨,也可提pr,issue等
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 封装JDBC—非框架开发必备的封装类
- Mybatis: 动手封装ORM框架
- 自定义MVC框架-封装模型层
- Flutter 基于Bloc框架的封装
- 优雅地实现Android主流图片加载框架封装,可无侵入切换框架
- 自定义MVC框架 -封装控制器层
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Rails
David Griffiths / O'Reilly Media / 2008-12-30 / USD 49.99
Figure its about time that you hop on the Ruby on Rails bandwagon? You've heard that it'll increase your productivity exponentially, and allow you to created full fledged web applications with minimal......一起来看看 《Head First Rails》 这本书的介绍吧!