当前位置:首页 >> 中医丰胸 >> SpringBoot自定义记事+异步+观察者模式实现业务日志保存

SpringBoot自定义记事+异步+观察者模式实现业务日志保存

发布时间:2023-04-29

MENT = '转换快照历史纪录' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

实体类:

import com.baomidou.mybatisplus.Annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import com.fasterxml.jackson.annotation.JsonFormat;import lombok.Data;import java.time.LocalDateTime;/** * 转换快照历史纪录表 sys_log * */@Data@TableName("sys_log")public class SysLog { private static final long serialVersionUID = 1L; /** * 快照字段 */ @TableId private Long id; /** * 转换模块化 */ private String title; /** * 业务并不一定(0其它 1新增 2修改 3删去) */ private Integer businessType; /** * 催促方式将 */ private String requestMethod; /** * 转换人员 */ private String operName; /** * 催促url */ private String operUrl; /** * 转换邮箱 */ private String operIp; /** * 转换时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime operTime;}四、主要功能

大体渐进:先为副本一个出处-------->凸来来进行赚取要留存的原始数据-------->一个发布新闻者来发布新闻要留存的原始数据-------->一个窃听者窃听后留存(异步)

完整项目架构图如下:

1. 编著出处import com.example.demo.constant.BusinessTypeEnum;import java.lang.annotation.*;/** * 自定义转换快照历史纪录出处 * @author wangzhenjun * @date 2022/10/26 15:37 */@Target(ElementType.METHOD) // 出处只能用于方式@Retention(RetentionPolicy.RUNTIME) // ;也出处的生命周期@Documentedpublic @interface Log { String value() default ""; /** * 模块化 */ String title() default "检验模块化"; /** * 功能 */ BusinessTypeEnum businessType() default BusinessTypeEnum.OTHER;}2. 业务并不一定枚举/** * @author wangzhenjun * @date 2022/10/26 11:22 */public enum BusinessTypeEnum { /** * 其它 */ OTHER(0,"其它"), /** * 新增 */ INSERT(1,"新增"), /** * 修改 */ UPDATE(2,"修改"), /** * 删去 */ DELETE(3,"删去"); private Integer code; private String message; BusinessTypeEnum(Integer code, String message) { this.code = code; this.message = message; } public Integer getCode() { return code; } public String getMessage() { return message; }}3. 编著薄片

这里小编是以薄片后来进行发起的,当然规约流程是要加异常后的薄片,这里以最简单的来进行检验哈,大家按需来进行添加!!

import com.example.demo.annotation.Log;import com.example.demo.entity.SysLog;import com.example.demo.listener.EventPubListener;import com.example.demo.utils.IpUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.time.LocalDateTime;/** * @author wangzhenjun * @date 2022/10/26 15:39 */@Aspect@Componentpublic class SysLogAspect { private final Logger logger = LoggerFactory.getLogger(SysLogAspect.class); @Autowired private EventPubListener eventPubListener; /** * 以出处所标注的方式作为切入点 */ @Pointcut("@annotation(com.example.demo.annotation.Log)") public void sysLog() {} /** * 在恰好之前织入 * @throws Throwable */ @After("sysLog()") public void doAfter(JoinPoint joinPoint) { Log log = ((MethodSignature) joinPoint.getSignature()).getMethod() .getAnnotation(Log.class); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String method = request.getMethod(); String url = request.getRequestURL().toString(); String ip = IpUtils.getIpAddr(request); SysLog sysLog = new SysLog(); sysLog.setBusinessType(log.businessType().getCode()); sysLog.setTitle(log.title()); sysLog.setRequestMethod(method); sysLog.setOperIp(ip); sysLog.setOperUrl(url); // 从登录之中token赚取登录人员信息才不会 sysLog.setOperName("我是检验人员"); sysLog.setOperTime(LocalDateTime.now()); // 发布新闻假消息 eventPubListener.pushListener(sysLog); logger.info("=======快照发送出乎意料,内容:{}",sysLog); }}4. ip辅助工具类import com.baomidou.mybatisplus.core.toolkit.StringUtils;import javax.servlet.http.HttpServletRequest;/** * @author wangzhenjun * @date 2022/10/26 16:27 * 赚取IP方式 * * @author jw */public class IpUtils { /** * 赚取客户端IP * * @param request 催促具体来说 * @return IP邮箱 */ public static String getIpAddr(HttpServletRequest request) { if (request == null) { return "unknown"; } String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Forwarded-For"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); } /** * 从多级反转挂名之中赢得第一个非unknown IP邮箱 * * @param ip 赢得的IP邮箱 * @return 第一个非unknown IP邮箱 */ public static String getMultistageReverseProxyIp(String ip) { // 多级反转挂名检验 if (ip != null && ip.indexOf(",")> 0) { final String[] ips = ip.trim().split(","); for (String subIp : ips) { if (false == isUnknown(subIp)) { ip = subIp; break; } } } return ip; } /** * 检验任意数组是否为不得而知,多用于检验HTTP催促就其 * * @param checkString 被检验的数组 * @return 是否不得而知 */ public static boolean isUnknown(String checkString) { return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); }}5. 政治事件发布新闻

政治事件发布新闻是由ApplicationContext具体来说来进行发布新闻的,直接注入适用才不会!适用观察者方式的目标:为了业务命题之间的解出耦,提高可扩展性。这种方式在spring和springboot底层是常有的,大家可以去看看。发布新闻者只需关注发布新闻假消息,窃听者只需窃听自己需的,不管谁发的,适用自己窃听条件才不会。

import com.example.demo.entity.SysLog;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Component;/** * @author wangzhenjun * @date 2022/10/26 16:38 */@Componentpublic class EventPubListener { @Autowired private ApplicationContext applicationContext; // 政治事件发布新闻方式 public void pushListener(SysLog sysLogEvent) { applicationContext.publishEvent(sysLogEvent); }}6. 窃听者

@Async:单独重启一个新寄存器去留存,提高稳定性!@EventListener:窃听

/** * @author wangzhenjun * @date 2022/10/25 15:22 */@Slf4j@Componentpublic class MyEventListener { @Autowired private TestService testService; // 重启异步 @Async // 重启窃听 @EventListener(SysLog.class) public void saveSysLog(SysLog event) { log.info("=====即将异步留存到索引======"); testService.saveLog(event); }}五、检验1. controller/** * @author wangzhenjun * @date 2022/10/26 16:51 */@Slf4j@RestController@RequestMapping("/test")public class TestController { @Log(title = "检验呢",businessType = BusinessTypeEnum.INSERT) @GetMapping("/saveLog") public void saveLog(){ log.info("我就是来检验一下是否出乎意料!"); }}2. service/** * @author wangzhenjun * @date 2022/10/26 16:55 */public interface TestService { int saveLog(SysLog sysLog);}/** * @author wangzhenjun * @date 2022/10/26 16:56 */@Servicepublic class TestServiceImpl implements TestService { @Autowired private TestMapper testMapper; @Override public int saveLog(SysLog sysLog) { return testMapper.insert(sysLog); }}3. mapper

这里适用mybatis-plus来进行留存

/** * @author wangzhenjun * @date 2022/10/26 17:07 */public interface TestMapper extends BaseMapper {}4. 检验 5. 索引 六、总结

铛铛铛,终于完成了!这个实战在应用软件必不可少的,每个项目搭成人不同,但是结果都是一样的,留存快照到原始数据,这样可以来进行操纵杆的点击来进行统计,分析方法那个功能是否往往适用,那些好像需最佳化。只要是有原始数据的好像,分析方法一下总不会有收获的!后面快照多了就行分库分表,ELK搭成。知道的越好多不知道的就越好多,这一次下来,知道下面要学什么了嘛!!

长期便秘是什么原因
治疗类风湿关节炎的首选药物
一吃辣就拉肚子是什么原因
肠胃炎拉肚子吃什么药
风湿保健
标签:
友情链接: