当前位置: 首页 > news >正文

网站建设在windos的设置刚做的网站怎么在百度上能搜到

网站建设在windos的设置,刚做的网站怎么在百度上能搜到,移动端网站建设费用,win8.1 做网站服务器文章目录 前言正文一、项目结构介绍二、核心类2.1 核心注解2.1.1 CLog 日志注解2.1.2 ProcessorBean 处理器bean 2.2 切面类2.3 自定义线程池2.4 工具类2.4.1 管理者工具类 2.5 测试2.5.1 订单创建处理器2.5.2 订单管理者2.5.3 订单控制器2.5.4 测试报文2.5.5 测试结果 附录1、… 文章目录 前言正文一、项目结构介绍二、核心类2.1 核心注解2.1.1 CLog 日志注解2.1.2 ProcessorBean 处理器bean 2.2 切面类2.3 自定义线程池2.4 工具类2.4.1 管理者工具类 2.5 测试2.5.1 订单创建处理器2.5.2 订单管理者2.5.3 订单控制器2.5.4 测试报文2.5.5 测试结果 附录1、其他相关文章 前言 关于操作日志记录在一个项目中是必要的。 本文基于 java8 和 SpringBoot 2.7 来实现此功能。 之前写过一个简单的接口报文日志打印的和本文的起始思路相同都是使用切面。但是本文功能更为强大也更复杂。文章见本文附录《SpringBoot自定义starter之接口日志输出》。 本文代码仓库https://gitee.com/fengsoshuai/custom-log2.git 正文 本文知识点如下 自定义注解SpringBoot使用切面全局异常处理器ThreadLocal的使用MDC传递日志ID登录拦截器日志拦截器自定义线程池SPEL表达式解析模版方法设计模式等。 一、项目结构介绍 其中 org.feng.clog 是核心代码区域。org.feng.test 是用于测试功能写的。 二、核心类 在项目启动时会把AbstractProcessorTemplate 的子类放入Spring容器。同时会执行注册处理器的方法其定义如下 package org.feng.clog;import lombok.extern.slf4j.Slf4j; import org.feng.clog.annotation.ProcessorBean; import org.feng.clog.utils.SpringBeanUtils;import javax.annotation.PostConstruct;/*** 处理器模板** author feng*/ Slf4j public abstract class AbstractProcessorTemplateT, R implements ProcessorT, R {protected void init(ProcessorContextT context) {}protected void after(ProcessorContextT context, R result) {}public R start(ProcessorContextT context) {init(context);// 直接调用handle会导致aop失效// R result handle(context);AbstractProcessorTemplateT, R template SpringBeanUtils.getByClass(this.getClass());R result template.handle(context);after(context, result);return result;}PostConstructprivate void registerProcessor() {if (this.getClass().isAnnotationPresent(ProcessorBean.class)) {ProcessorBean processorBean this.getClass().getDeclaredAnnotation(ProcessorBean.class);log.info(ProcessorBean Register, action is {}, processor is {}, processorBean.action(), this.getClass().getName());ProcessorFactory.register(processorBean.action(), this);}} } 2.1 核心注解 2.1.1 CLog 日志注解 package org.feng.clog.annotation;import org.feng.clog.enums.ActionTypeEnum; import org.feng.clog.enums.ModuleEnum;import java.lang.annotation.*;/*** 日志注解/br* pre* ul使用示例* liCLog(template 这是简单模版无参数,actionType ActionTypeEnum.UPDATE,actionIdEl {#userReq.id},moduleEl 1)/li* liCLog(template 带参数模版学生名称{#userReq.name},班级名称{#userReq.classReq.name},actionTypeStr 这是操作,actionIdEl {#userReq.id})/li* liCLog(template 带参数计算模版{#userReq.classReq.number 20?大班:小班},actionTypeStr 这是操作,actionIdEl {#userReq.id})/li* liCLog(template 复杂模版{#userReq.classReq.number 20?大班:(这是名称:).concat(#userReq.name).concat(,这是年龄).concat(#userReq.age)},actionTypeStr 这是操作,actionIdEl {#userReq.id})/li* liCLog(template 自定义表达式处理{SfObjectUtil.isEmpty(#userReq.id)?id为0或者为空:id不为0或者为空},actionTypeStr 这是操作,actionIdEl {#userReq.id})/li* liCLog(template 自定义处理{logDesc},actionTypeStr 这是操作,actionIdEl {id})/li* /ul* /pre** author feng*/ Documented Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) public interface CLog {/*** 日志模版*/String template();/*** 模块*/ModuleEnum module() default ModuleEnum.DEFAULT;/*** 所属模块名*/String moduleStr() default ;/*** 所属模块名/br* 变量/表达式获取*/String moduleEl() default ;/*** 操作类型*/ActionTypeEnum actionType() default ActionTypeEnum.DEFAULT;/*** 操作类型优先级高于枚举不为空时强制读取此值*/String actionTypeStr() default ;/*** 操作类型/br* 变量/表达式获取*/String actionTypeEl() default ;/*** 业务操作唯一值/br* 变量/表达式获取*/String actionIdEl() default ;/*** 业务操作唯一值,多值*/String actionIds() default ;/*** 扩展字段*/String ext() default ; } 2.1.2 ProcessorBean 处理器bean package org.feng.clog.annotation;import org.feng.clog.enums.ActionTypeEnum;import java.lang.annotation.*;/*** 处理器bean** author feng*/ Documented Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface ProcessorBean {ActionTypeEnum action(); }2.2 切面类 package org.feng.clog.aspect;import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.feng.clog.LogId; import org.feng.clog.LogRecordContext; import org.feng.clog.annotation.CLog; import org.feng.clog.config.LogCustomerConfig; import org.feng.clog.enums.ActionTypeEnum; import org.feng.clog.enums.ModuleEnum; import org.feng.clog.utils.SpELParserUtils; import org.feng.clog.utils.StringUtil; import org.feng.clog.utils.UserUtil; import org.feng.clog.vo.UserVo; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.util.*; import java.util.concurrent.Executor; import java.util.regex.Matcher; import java.util.regex.Pattern;/*** 日志切面** author feng*/ Aspect Component Slf4j public class LogAspect {private static final Pattern BRACES_PATTERN Pattern.compile(\\{.*?});Resource(name logThreadPoolTaskExecutor)private Executor executor;Pointcut(annotation(org.feng.clog.annotation.CLog))private void pointCut() {}AfterReturning(value pointCut())public void after(JoinPoint joinPoint) {try {addLog(joinPoint);} finally {LogRecordContext.clean();}}public void addLog(JoinPoint joinPoint) {String logId LogId.get();UserVo userVo UserUtil.get();MapString, String logRecordMap LogRecordContext.get();executor.execute(() - {try {// 传递logId到异步线程LogId.put(logId);// 获取方法入参MethodSignature signature (MethodSignature) joinPoint.getSignature();Object[] args joinPoint.getArgs();// 获取注解CLog cLog signature.getMethod().getDeclaredAnnotation(CLog.class);// 获取模版中的参数如果存在参数并拼接ListString templateParameters getTemplateParameters(cLog.template());buildTemplateData(templateParameters, signature, args, logRecordMap);String template cLog.template();for (String templateParameter : templateParameters) {template template.replace(templateParameter, logRecordMap.get(templateParameter));}// 获取moduleString module getModule(cLog, signature, args, logRecordMap);// 获取actionTypeString actionType getActionType(cLog, signature, args, logRecordMap);// 获取actionIdListString actionIds getActionId(cLog, signature, args, logRecordMap);// 获取扩展字段JSONObject ext getExt(cLog, signature, args, logRecordMap);if (StringUtil.isNotBlank(template)) {for (String actionId : actionIds) {log.info(记录日志user{}, template{}, module{}, actionType{}, actionId{}, ext{}, userVo, template, module, actionType, actionId, ext);// todo 日志落库}} else {log.info(设置日志数据失败不满足注解条件);}} catch (Exception e) {log.warn(设置日志异常:, e);}});}private ListString getTemplateParameters(String template) {ListString parameters new ArrayList();Matcher matcher BRACES_PATTERN.matcher(template);while (matcher.find()) {parameters.add(matcher.group());}return parameters;}private void buildTemplateData(ListString parameters, MethodSignature signature, Object[] args, MapString, String map) {for (String el : parameters) {// 如果EL表达式为空则直接下一个if (!StringUtil.isNotBlank(el)) {continue;}String spEl el;// 兼容自定义数据spEl getEl(spEl);if (map.containsKey(spEl)) {map.put({ spEl }, map.get(spEl));continue;}// 自定义类处理spEl parseCustomerMethodEl(spEl);// El执行if (spEl.contains(#)) {String value SpELParserUtils.parse(signature.getMethod(), args, spEl, String.class);map.put(el, value);} else {map.put(el, );}}}private String getModule(CLog cLog, MethodSignature signature, Object[] args, MapString, String map) {// 设置了module枚举时优先获取枚举对应的描述if (!ModuleEnum.DEFAULT.equals(cLog.module())) {return cLog.module().getDesc();}// 设置了moduleStr时if (StringUtil.isNotBlank(cLog.moduleStr())) {return cLog.moduleStr();}// 设置了moduleEl时if (StringUtil.isNotBlank(cLog.moduleEl())) {try {String el cLog.moduleEl();el getEl(el);// 处理自定义的elif (map.containsKey(el)) {return map.get(el);}// 处理自定义方法elel parseCustomerMethodEl(el);// 执行elreturn SpELParserUtils.parse(signature.getMethod(), args, el, String.class);} catch (Exception e) {log.error(日志切面获取module错误, e);}}return null;}private String getActionType(CLog cLog, MethodSignature signature, Object[] args, MapString, String map) {// 设置了actionType枚举时优先获取枚举对应的描述if (!ActionTypeEnum.DEFAULT.equals(cLog.actionType())) {return cLog.actionType().getDesc();}// 设置了actionTypeStr时if (StringUtil.isNotBlank(cLog.actionTypeStr())) {return cLog.actionTypeStr();}// 设置了actionTypeEl时if (StringUtil.isNotBlank(cLog.actionTypeEl())) {String el cLog.actionTypeEl();el getEl(el);// 处理自定义的elif (map.containsKey(el)) {return map.get(el);}// 处理自定义方法elel parseCustomerMethodEl(el);// 执行elreturn SpELParserUtils.parse(signature.getMethod(), args, el, String.class);}return null;}private ListString getActionId(CLog cLog, MethodSignature signature, Object[] args, MapString, String map) {// 设置了actionIdEl时if (StringUtil.isNotBlank(cLog.actionIdEl())) {if (map.containsKey(cLog.actionIdEl())) {return Collections.singletonList(map.get(cLog.actionIdEl()));}String el cLog.actionIdEl();el getEl(el);// 处理自定义elif (map.containsKey(el)) {return Collections.singletonList(map.get(el));}// 执行elreturn Collections.singletonList(SpELParserUtils.parse(signature.getMethod(), args, el, String.class));}// 设置了actionIds时if (StringUtil.isNotBlank(cLog.actionIds())) {String el getEl(cLog.actionIds());if (map.containsKey(el)) {return Arrays.asList(map.get(el).split(,));}}return Collections.singletonList(System.currentTimeMillis() * 10 new Random().nextInt(10000) );}private JSONObject getExt(CLog cLog, MethodSignature signature, Object[] args, MapString, String map) {// 如果EL表达式为空则直接结束if (!StringUtil.isNotBlank(cLog.ext())) {return null;}String spEl cLog.ext();//兼容自定义数据spEl getEl(spEl);if (map.containsKey(spEl)) {String value map.get(spEl);if (StringUtil.isNotBlank(value)) {try {return JSONObject.parseObject(value);} catch (Exception e) {log.info(JSON转换失败:{},{}, value, e.getMessage());return null;}}return null;}// 自定义类处理spEl parseCustomerMethodEl(spEl);// El执行if (spEl.contains(#)) {String value SpELParserUtils.parse(signature.getMethod(), args, spEl, String.class);if (StringUtil.isNotBlank(value)) {try {return JSONObject.parseObject(value);} catch (Exception e) {log.info(JSON转换失败:{},{}, value, e.getMessage());return null;}}return null;}return null;}private String parseCustomerMethodEl(String el) {for (String key : LogCustomerConfig.getCustomerMethod().keySet()) {if (el.contains(key)) {String className key.split(\\.)[0];el el.replace(className, T( LogCustomerConfig.getCustomerMethod().get(key) ));}}return el;}private String getEl(String str) {str str.replaceAll(\\{, );str str.replaceAll(}, );return str;}} 2.3 自定义线程池 package org.feng.clog.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor;/*** 线程池配置** author feng*/ Configuration EnableAsync public class ThreadPoolConfig {Bean(name logThreadPoolTaskExecutor)public Executor initLogCpuExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setCorePoolSize(Runtime.getRuntime().availableProcessors() 1);executor.setMaxPoolSize(150);executor.setQueueCapacity(50);executor.setKeepAliveSeconds(60);executor.setThreadNamePrefix(log-thread-pool-);executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();executor.setTaskDecorator(runnable - runnable);return executor;} } 2.4 工具类 2.4.1 管理者工具类 package org.feng.clog.utils;import org.feng.clog.AbstractProcessorTemplate; import org.feng.clog.ProcessorContext; import org.feng.clog.ProcessorFactory;/*** 管理工具** author feng*/ public class ManagerUtil {public static R, T R handle(ProcessorContextT context) {AbstractProcessorTemplateT, R processor ProcessorFactory.getProcessor(context.getAction());if (processor null) {throw new RuntimeException(未找到 context.getAction() 对应的处理器);}return processor.start(context);} } 2.5 测试 2.5.1 订单创建处理器 package org.feng.test;import lombok.extern.slf4j.Slf4j; import org.feng.clog.AbstractProcessorTemplate; import org.feng.clog.LogRecordContext; import org.feng.clog.ProcessorContext; import org.feng.clog.annotation.CLog; import org.feng.clog.annotation.ProcessorBean; import org.feng.clog.enums.ActionTypeEnum; import org.feng.clog.enums.ModuleEnum; import org.feng.clog.utils.StringUtil; import org.springframework.stereotype.Service;/*** 创建订单处理器** author feng*/ Slf4j Service ProcessorBean(action ActionTypeEnum.ORDER_CREATE) public class OrderCreateProcessor extends AbstractProcessorTemplateOrderCreateReq, Boolean {Overrideprotected void init(ProcessorContextOrderCreateReq context) {preHandleReq(context.getData());}OverrideCLog(template 测试日志记录{testK1}, module ModuleEnum.ORDER, actionType ActionTypeEnum.ORDER_CREATE,actionIdEl {#context.data.orderNum}, ext {JacksonUtil.toJSONString(#context.data)})public Boolean handle(ProcessorContextOrderCreateReq context) {LogRecordContext.put(testK1, 3wewd2);OrderCreateReq orderCreateReq context.getData();log.info(处理--创建订单{}, orderCreateReq.getOrderNum());return true;}Overrideprotected void after(ProcessorContextOrderCreateReq context, Boolean result) {// todo 后置操作}private void preHandleReq(OrderCreateReq req) {// todo 参数校验// 例如校验参数if (StringUtil.isBlank(req.getOrderNum())) {throw new IllegalArgumentException(订单号不能为空);}} } 2.5.2 订单管理者 package org.feng.test;import org.feng.clog.ProcessorContext; import org.feng.clog.enums.ActionTypeEnum; import org.feng.clog.utils.ManagerUtil; import org.springframework.stereotype.Component;/*** 订单管理** author feng*/ Component public class OrderManager {/*** 创建订单*/public Boolean createOrder(OrderCreateReq req) {ProcessorContextOrderCreateReq processorContext new ProcessorContext();processorContext.setAction(ActionTypeEnum.ORDER_CREATE);processorContext.setData(req);return ManagerUtil.handle(processorContext);} } 2.5.3 订单控制器 package org.feng.test;import org.feng.clog.utils.ResultUtil; import org.feng.clog.vo.ResultVo; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 控制器** author feng*/ RestController RequestMapping(order) public class OrderController {Resourceprivate OrderManager orderManager;// WithoutLoginPostMapping(/test1)public ResultVoString test1(RequestBody OrderCreateReq req) {// 创建Boolean started orderManager.createOrder(req);return ResultUtil.success(success started);} } 2.5.4 测试报文 {orderNum: 1001,type: 1,senderName: ,likes: [1, 2, 3] }2.5.5 测试结果 控制台日志输出 2024-02-28 11:48:40.102 INFO 92309 --- [log-thread-pool-1] org.feng.clog.aspect.LogAspect.lambda$addLog$0(LogAspect.java:95) : [logIdd3b0dc267ce64dfa8a987e8eb6aad4ba] 记录日志userUserVo(id1001, usernamefeng123, phone18143431243, emailnull), template测试日志记录3wewd2, module订单, actionType订单创建, actionId1001, ext{senderName:,orderNum:1001,type:1,likes:[1,2,3]} 可以看到日志中记录了logId以及日志注解对应的信息。 附录 1、其他相关文章 SpringBoot自定义starter之接口日志输出SpringBoot使用线程池之ThreadPoolTaskExecutor和ThreadPoolExecutor
http://www.zqtcl.cn/news/568513/

相关文章:

  • 外贸在线网站建站wordpress开放注册
  • 桂林餐饮兼职网站建设如何在百度上建网站
  • 怎样做免费网站的推广便宜点的网站空间
  • 中国建设部网站失信名单自己做公司网站难吗
  • 济南做网站需要多少钱园区网站到底怎么建设
  • 武清做网站的公司wordpress商城
  • 网站建设的实训技术总结sql 新建网站
  • 开发网站多少钱网站文件目录结构
  • 网站规划和建设的步骤做网站用的各种图标大全
  • 网站公司查询js代码网站大全
  • 湘潭网站建设价格最新新闻热点事件100字
  • 音乐网站程序源码wordpress模板中文版
  • 网站建设计划表wordpress主题 大
  • 在手机制作网站书店网站建设技术风险
  • 爱站网域名查询wordpress自定义标题关键词描述
  • 西安学校网站建设报价建盏
  • 网页 网站 区别东莞手机app开发
  • 空压机网站开发公司广州海珠区有什么好玩的景点
  • 什么网站可以做期货企业解决方案服务协议
  • 西安汽车网站制作手机软件制作网站平台
  • 微信的微网站介绍自己的家乡遵义网站建设
  • 爱站seo东莞网站建设要注意什么
  • 惠州网站建设 英语6wordpress 表格提交
  • 做网站15年多少钱一度电
  • 北京网站域名快速备案外贸网站优化价格
  • 做网站 工资高吗免费建站的站点网站
  • 个人做营利性质网站会怎么样qq邮箱官方网站
  • 网站怎么做等级保护产品展示小程序
  • 奉贤网站建设专家高端自适应网站设计
  • 网站正在建设中 动态徐州网站建设方案咨询