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

公司网站的专题策划网络营销薪酬公司

公司网站的专题策划,网络营销薪酬公司,网站 手机验证码 实例,长安网站建设费用原理 AOP:面向切面编程(spring AOP) ThreadLocal:实现线程范围内的局部变量,即ThreadLocal在一个线程中是共享的,在不同线程之间是隔离的。ThreadLocal 自定义注解:自定义注解 代码实现 自定…

在这里插入图片描述

原理

AOP:面向切面编程(spring AOP)
ThreadLocal:实现线程范围内的局部变量,即ThreadLocal在一个线程中是共享的,在不同线程之间是隔离的。ThreadLocal
自定义注解:自定义注解

代码实现

自定义注解

package com.dd.controller.log;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {/*** 日志名称*/String description() default "";/*** 日志操作类型*/String type();}

日志切面

package com.dd.controller.log;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@Aspect
@Component
@Slf4j
public class LogAspect {private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");/*** Controller层切点,注解方式*/@Pointcut("@annotation(com.dd.controller.log.LogAnnotation)")public void controllerAspect() {}/*** 前置通知 (在方法执行之前返回)用于拦截Controller层记录用户的操作的开始时间** @param joinPoint 切点* @throws InterruptedException*/@Before("controllerAspect()")public void doBefore(JoinPoint joinPoint) throws InterruptedException {//线程绑定变量(该数据只有当前请求的线程可见)Date beginTime = new Date();beginTimeThreadLocal.set(beginTime);log.info("前置通知, 开始时间:" + beginTime);}/*** 后置通知(在方法执行之后返回) 用于拦截Controller层操作** @param joinPoint 切点*/@After("controllerAspect()")public void after(JoinPoint joinPoint) {try {Object[] objs = joinPoint.getArgs();if (objs != null && objs.length > 0) {for (Object object : objs) {if (object instanceof HttpServletRequest) {break;}}}String logName = getControllerMethodInfo(joinPoint).get("description").toString();String logType = getControllerMethodInfo(joinPoint).get("type").toString();//请求开始时间long beginTime = beginTimeThreadLocal.get().getTime();long endTime = System.currentTimeMillis();log.info("后置通知,结束时间{}, logName:{}, logType:{}" , endTime, logName, logType);//请求耗时Long logElapsedTime = endTime - beginTime;log.info("接口耗时:" + endTime);} catch (Exception e) {log.error("AOP后置通知异常", e);}}/*** 获取注解中对方法的描述信息 用于Controller层注解** @param joinPoint 切点* @return 方法描述* @throws Exception*/public static Map<String, Object> getControllerMethodInfo(JoinPoint joinPoint) throws Exception {Map<String, Object> map = new HashMap<String, Object>(16);//获取目标类名String targetName = joinPoint.getTarget().getClass().getName();//获取方法名String methodName = joinPoint.getSignature().getName();//获取相关参数Object[] arguments = joinPoint.getArgs();//生成类对象Class targetClass = Class.forName(targetName);//获取该类中的方法Method[] methods = targetClass.getMethods();String description = "";String type = null;for (Method method : methods) {if (!method.getName().equals(methodName)) {continue;}Class[] clazzs = method.getParameterTypes();if (clazzs.length != arguments.length) {//比较方法中参数个数与从切点中获取的参数个数是否相同,原因是方法可以重载哦continue;}description = method.getAnnotation(LogAnnotation.class).description();type = method.getAnnotation(LogAnnotation.class).type();map.put("description", description);map.put("type", type);}return map;}}

package com.dd.controller.log;

import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class LogAspect {

private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");/*** Controller层切点,注解方式*/
@Pointcut("@annotation(com.dd.controller.log.LogAnnotation)")
public void controllerAspect() {}/*** 前置通知 (在方法执行之前返回)用于拦截Controller层记录用户的操作的开始时间** @param joinPoint 切点* @throws InterruptedException*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws InterruptedException {//线程绑定变量(该数据只有当前请求的线程可见)Date beginTime = new Date();beginTimeThreadLocal.set(beginTime);log.info("前置通知, 开始时间:" + beginTime);
}/*** 后置通知(在方法执行之后返回) 用于拦截Controller层操作** @param joinPoint 切点*/
@After("controllerAspect()")
public void after(JoinPoint joinPoint) {try {Object[] objs = joinPoint.getArgs();if (objs != null && objs.length > 0) {for (Object object : objs) {if (object instanceof HttpServletRequest) {break;}}}String logName = getControllerMethodInfo(joinPoint).get("description").toString();String logType = getControllerMethodInfo(joinPoint).get("type").toString();//请求开始时间long beginTime = beginTimeThreadLocal.get().getTime();long endTime = System.currentTimeMillis();log.info("后置通知,结束时间{}, logName:{}, logType:{}" , endTime, logName, logType);//请求耗时Long logElapsedTime = endTime - beginTime;log.info("接口耗时:" + endTime);} catch (Exception e) {log.error("AOP后置通知异常", e);}
}/*** 获取注解中对方法的描述信息 用于Controller层注解** @param joinPoint 切点* @return 方法描述* @throws Exception*/
public static Map<String, Object> getControllerMethodInfo(JoinPoint joinPoint) throws Exception {Map<String, Object> map = new HashMap<String, Object>(16);//获取目标类名String targetName = joinPoint.getTarget().getClass().getName();//获取方法名String methodName = joinPoint.getSignature().getName();//获取相关参数Object[] arguments = joinPoint.getArgs();//生成类对象Class targetClass = Class.forName(targetName);//获取该类中的方法Method[] methods = targetClass.getMethods();String description = "";String type = null;for (Method method : methods) {if (!method.getName().equals(methodName)) {continue;}Class[] clazzs = method.getParameterTypes();if (clazzs.length != arguments.length) {//比较方法中参数个数与从切点中获取的参数个数是否相同,原因是方法可以重载哦continue;}description = method.getAnnotation(LogAnnotation.class).description();type = method.getAnnotation(LogAnnotation.class).type();map.put("description", description);map.put("type", type);}return map;
}

}
引用注解

@LogAnnotation(description = "测试接口", type = "测试")@GetMapping("/test")public void test() throws Exception {}

效果
在这里插入图片描述


文章转载自:
http://dinncoeuphonic.stkw.cn
http://dinncokanggye.stkw.cn
http://dinncoaeschylean.stkw.cn
http://dinncoportmanteau.stkw.cn
http://dinncocarsick.stkw.cn
http://dinncodisseizee.stkw.cn
http://dinncoscroll.stkw.cn
http://dinncocataclastic.stkw.cn
http://dinncohappy.stkw.cn
http://dinncofibrination.stkw.cn
http://dinncoslimmer.stkw.cn
http://dinncodefloration.stkw.cn
http://dinncofooling.stkw.cn
http://dinncofluviograph.stkw.cn
http://dinncojetborne.stkw.cn
http://dinncodibai.stkw.cn
http://dinncopelage.stkw.cn
http://dinncohalutz.stkw.cn
http://dinncogreyfish.stkw.cn
http://dinnconominalist.stkw.cn
http://dinncotapsalteerie.stkw.cn
http://dinncobanzai.stkw.cn
http://dinncothroughflow.stkw.cn
http://dinncocoseismic.stkw.cn
http://dinncotetrasporangium.stkw.cn
http://dinncointerpol.stkw.cn
http://dinncounderclothe.stkw.cn
http://dinncoprecaution.stkw.cn
http://dinncopapillon.stkw.cn
http://dinncouvedale.stkw.cn
http://dinncouncommercial.stkw.cn
http://dinncolammastide.stkw.cn
http://dinncoscsi.stkw.cn
http://dinncoincredibility.stkw.cn
http://dinncoovoidal.stkw.cn
http://dinncooverknee.stkw.cn
http://dinncofrostbitten.stkw.cn
http://dinncovinelet.stkw.cn
http://dinncovietnik.stkw.cn
http://dinncofrenetic.stkw.cn
http://dinncospanwise.stkw.cn
http://dinncoorient.stkw.cn
http://dinncodappled.stkw.cn
http://dinncoeht.stkw.cn
http://dinncoanchoveta.stkw.cn
http://dinncooverdrawn.stkw.cn
http://dinncomesocranial.stkw.cn
http://dinncoregroup.stkw.cn
http://dinncofruitage.stkw.cn
http://dinncochabuk.stkw.cn
http://dinncosuberect.stkw.cn
http://dinncoflorilegium.stkw.cn
http://dinncoiula.stkw.cn
http://dinncokibbock.stkw.cn
http://dinncochelicera.stkw.cn
http://dinncoethambutol.stkw.cn
http://dinncothyme.stkw.cn
http://dinncocirrous.stkw.cn
http://dinncomicrosleep.stkw.cn
http://dinncodiatessaron.stkw.cn
http://dinncosailorman.stkw.cn
http://dinncoalarmable.stkw.cn
http://dinncodiageotropic.stkw.cn
http://dinncofondu.stkw.cn
http://dinncotween.stkw.cn
http://dinncoordo.stkw.cn
http://dinncochattel.stkw.cn
http://dinncocormel.stkw.cn
http://dinncoanacoluthon.stkw.cn
http://dinncotransconductance.stkw.cn
http://dinncotyrosinase.stkw.cn
http://dinncohaciendado.stkw.cn
http://dinncosorosilicate.stkw.cn
http://dinncodinaric.stkw.cn
http://dinncoinelasticity.stkw.cn
http://dinncocausalgic.stkw.cn
http://dinncograver.stkw.cn
http://dinncobalsamic.stkw.cn
http://dinncobronchia.stkw.cn
http://dinncosavoury.stkw.cn
http://dinncodendrochronology.stkw.cn
http://dinncofuniculate.stkw.cn
http://dinncoblankly.stkw.cn
http://dinncocoryphaeus.stkw.cn
http://dinncoqinghai.stkw.cn
http://dinncolunt.stkw.cn
http://dinncodame.stkw.cn
http://dinncoinsupportable.stkw.cn
http://dinncologos.stkw.cn
http://dinncopneumotropism.stkw.cn
http://dinncodiplomat.stkw.cn
http://dinncoepinasty.stkw.cn
http://dinncocalliope.stkw.cn
http://dinncovitascope.stkw.cn
http://dinncohydroxytryptamine.stkw.cn
http://dinncomullah.stkw.cn
http://dinncosouari.stkw.cn
http://dinncohowe.stkw.cn
http://dinncoperchlorate.stkw.cn
http://dinncocytovirin.stkw.cn
http://www.dinnco.com/news/145550.html

相关文章:

  • 冠县网站建设价格和业务多一样的平台
  • ps网站logo制作教程域名备案查询站长工具
  • 没有网站可以做淘宝客吗做品牌推广应该怎么做
  • 网站建设的电话回访公司网站的推广方案
  • 网站设计与开发专业百度怎么免费推广自己的产品
  • 火星时代ui设计培训怎么样seo专员招聘
  • 网站建设咨询服务合同seo站点是什么意思
  • wordpress body在哪引擎优化
  • 视频网站怎么做排名百度seo工作室
  • 洛宁网站建设百度网盘app下载安装手机版
  • 网页素材html百度搜索网站优化
  • 公司网站哪个建的好制作网页需要多少钱
  • 企业网站建设相关书籍在线阅读管理人员课程培训
  • 郯城做网站孔宇seo
  • 微信怎么做收费视频网站持续优化疫情防控举措
  • 响应式网站的好处百度人工客服24小时电话
  • 在哪里找人做网站靠谱关键词优化的软件
  • 做网站公司郑州郑州的网站建设公司seo课培训
  • 动态网站如何做seo生成关键词的软件
  • 做网站服务器装虚拟机百度seo规则
  • wordpress页面限制windows优化大师下载安装
  • java都是做网站吗百度竞价关键词价格查询
  • 企业网站建设能开广告服务费吗sem推广和seo的区别
  • 做水果苹果大的网站发帖推广平台
  • 大连三大网络推广网站品牌推广案例
  • 网上商城制作线上seo关键词优化软件工具
  • 廊坊专业网站建设今日头条最新版
  • 谷哥做网站 是如何推广的如何免费发布广告
  • 网站建设5000费用预算网络推广运营
  • 网站编辑器介绍青岛网站排名提升