1.记录
之前学习RequestContextHolder只是粗略的过了一遍,实际开发中 并没有找到使用场景, 最近学习 Ruoyi源码倒是有所感悟。
2.RequestContextHolder的使用
是Spring框架提供的一个工具类,用于在非Web MVC的上下文中访问当前的HTTP请求相关的信息。在Spring的Web环境中,每个HTTP请求都会被封装在一个HttpServletRequest
对象中,并且这个请求对象会被绑定到一个线程上,这样在同一个线程内处理请求的不同部分时,都可以访问到这个请求的信息
//两个方法在没有使用JSF的项目中是没有区别的
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
//RequestContextHolder.getRequestAttributes();
//从session里面获取对应的值
String str = (String) requestAttributes.getAttribute("name",RequestAttributes.SCOPE_SESSION);
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
HttpServletResponse response = ((ServletRequestAttributes)requestAttributes).getResponse(
request和response怎么和当前请求挂钩?
首先分析RequestContextHolder这个类,里面有两个ThreadLocal保存当前线程下的request
//得到存储进去的request
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
new NamedThreadLocal<RequestAttributes>("Request attributes");
//可被子线程继承的request
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
new NamedInheritableThreadLocal<RequestAttributes>("Request context");
再看`getRequestAttributes()`方法,相当于直接获取ThreadLocal里面的值,这样就保证了每一次获取到的Request是该请求的request
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = requestAttributesHolder.get();
if (attributes == null) {
attributes = inheritableRequestAttributesHolder.get();
}
return attributes;
}
3.使用RequestContextHolder对表格的Page进行处理,简化开发
Rouyi中的执行过程【uml时序图】
代码执行过程
- 在 RyGoodsController 的 list 方法中,首先调用
startPage()
初始化分页参数。 startPage()
方法在 BaseController 中调用了 PageUtils 类的startPage()
静态方法。- PageUtils 类的
startPage()
方法调用了 TableSupport 类的buildPageRequest()
方法,用于构建一个封装分页请求的对象。 - TableSupport 类的
buildPageRequest()
方法从请求参数中获取分页参数,如页面大小、排序列和升序/降序标志。 - ServletUtils 类的
getParameter()
方法用于从请求中获取参数值。 - ServletUtils 类的
getRequest()
方法用于获取当前的请求对象。 - 最终,RequestContextUtils 类的
getRequestAttributes()
方法用于获取当前请求的 RequestAttributes 对象,从而能够访问到请求的相关信息。
可以看到合理的使用RequestContextHolder可以在前后端约定好分页参数的前提下,对表单数据进行分页处理,能够简化代码,统一风格
- 前端:提供统一的分页组件(如pagination),前端通过Ajax请求时携带分页信息(如当前页码pageNum和每页数量pageSize)。
- 后端:通过
TableSupport
工具类中的buildPageRequest()
方法自动从请求中提取分页参数,并封装成PageDomain
对象。这样,业务逻辑代码无需直接处理分页参数,而是直接使用PageDomain
对象。