SpringMVC的Controller中使用线程安全的初始化
因为SpringMVC的Controller默认是单例, 在这种情况下, Controller中使用的私有变量必须也是单例, 例如各种service, 否则会有多线程访问数据互相修改的问题.
对于需要对一类Controller做相同初始化的需求, 可以通过@ModelAttribute("some-variable") public init() 这样的方法解决.
首先创建一个基类如BasicController, 构造一个拦截器, 对基类实现preHandle(), postHandle()方法
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception { RequestBean requestBean = (RequestBean)request.getAttribute(RequestBean.ATTR_KEY); if (requestBean != null) { requestBean.destroy(); request.removeAttribute(RequestBean.ATTR_KEY); long current = System.currentTimeMillis(); logger.debug("Page end: " + current + ", time: " + (current - requestBean.getTimestamp()) + " milliseconds"); } } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) throws Exception { if (handler instanceof HandlerMethod && mav != null) { HandlerMethod hm = (HandlerMethod)handler; if (BasicController.class.isAssignableFrom(hm.getBean().getClass())) { mav.addObject("sys_config", Config.getConfigs()); } } } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long timestamp = System.currentTimeMillis(); logger.debug("Page start: " + timestamp); if (handler instanceof HandlerMethod) { HandlerMethod hm = (HandlerMethod)handler; if (BasicController.class.isAssignableFrom(hm.getBean().getClass())) { RequestBean requestBean = new RequestBean(request, response, timestamp); request.setAttribute(RequestBean.ATTR_KEY, requestBean); } } return true; }
然后在BasicController中, 通过如下形式对每次访问作初始化
@ModelAttribute("requestBean") public RequestBean initRequest(HttpServletRequest request) { return (RequestBean)request.getAttribute(RequestBean.ATTR_KEY); }
然后在Controller方法中, 就可以直接引用这个初始化好的变量了
@RequestMapping(value = {"/edit","/add"}, method = RequestMethod.GET) public String doEdit( @ModelAttribute("requestBean") RequestBean rb) { ... }
@ModelAttribute("requestBean")
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程