再次理解aspect执行顺序
参看文章 https://blog.csdn.net/qq_32331073/article/details/80596084
这里给一个共用变量的列子:切面在进入Method前,先创建一个bean,然后放到ThradLocal(线程内部的存储类)中,然后在接入点中使用get()获取
@Aspect
@Component("httpLogAspect")
public class HttpLogAspect implements Ordered {
@Around("httpLogAroundPointCut()")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
//.......逻辑处理
ExpInvokeLogDto log = new ExpInvokeLogDto();
ExpInvokeLogDto.HTTP_LOG.set(log);
//......逻辑处理
}
}
共用的变量:
public class ExpInvokeLogDto{
/**
* http日志记录请求
*/
public static final ThreadLocal<ExpInvokeLogDto> HTTP_LOG = new ThreadLocal<>();
/**
* 获取线程的接口日志对象
* @return
*/
public static final ExpInvokeLogDto get(){
ExpInvokeLogDto log = HTTP_LOG.get();
if (log == null) {
log = new ExpInvokeLogDto();
HTTP_LOG.set(log);
}
return log;
}
public class A{
@HttpLog
public BaseResponse sendOrder(){
ExpInvokeLog expInvokeLog =ExpInvokeLogDto.get();
//......逻辑处理
}
......
}
}
这里说明一下:无特殊情况(比如新建了线程,或@Async异步线程),一个请求就是一个线程,即从控制层某个方法开始,后面调用到的所有方法都属于同一个线程。
可以在debug的时候看,往下一直走(进调用方法,再进调用方法),可以看到线程永远是同一个。
,
注意:现在线程大多被线程池管理,线程结束后不一定会注销而是被重用(如:tomcatx线程池,rabbitma线程池),而ThreadLocal与线程生命周期一样,所以,当线程结束时,要手动让ThreadLocal这个线程本地变量为null或被清除clear.
一个线程同时只能处理一个任务,一个任务可以同时被多个线程处理[注意多线程安全问题]。
线程池中,连接数不代表线程数;可以参考下面文章
详解tomcat的连接数与线程池