簡體   English   中英

如果我使用 @ControllerAdvice 填充 @ModelAttribute 是否會發生任何沖突

[英]Will I have any collisions coming from the @ControllerAdvice if I use it to populate a @ModelAttribute

這是 web 入口點的主控制器

@Controller
@RequestMapping("/webapp")
public class WebAppController {

@RequestMapping(value = "/home/{authKey}",method = RequestMethod.GET)
String index(@ModelAttribute MyMeta myMeta, Model model){

    System.out.println("Token: "+myMeta.getAccessToken());

    return "index";
}

@RequestMapping(value = "/config/{authKey}",method = RequestMethod.GET)
String config(@ModelAttribute MyMeta myMeta, Model model){

    return "configure";
}
}

現在,如果您查看攔截器,您可以看到我是如何創建@ModelAttribute 的,並查看實現

@Component
@ControllerAdvice
public class SessionInterceptor implements AsyncHandlerInterceptor {

MyMeta myMeta;

...

@ModelAttribute
public MyMeta getTest() {
    return this.myMeta;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {

...

// parse the key from the request

... 

MetaMagicKey metaMagicKey = metaMagicKeyRepo.findKeyByMagicKey(key);

// do work here query my DB and build stuff

...

// assign the queried data built into object
this.myMeta = metaMagicKey.getId().getMyMeta();

return true;
}

我的問題是,我不知道 Springboot 的真正交互方式,所以我擔心如果執行此操作的人太多,我可能會發生一些對象交換或某種碰撞? 確實沒有一種干凈的方法可以做到這一點,我所做的所有研究都在使用 HttpServletRequest#setAttribute() 和使用 @ModelAttribute 之間徘徊,我喜歡上面選擇的路線,因為它很容易在我的方法中實現.

Springboot 1.4.2 - Java 8

編輯:


我最終嘗試的是這個,基於我讀過的幾頁。

我創建了一個新組件:

@Component
@RequestScope
public class HWRequest implements Serializable {

private MyMeta myMeta;

public MyMeta getMyMeta() {
    return myMeta;
}

public void setMyMeta(MyMeta myMeta) {
    this.myMeta = myMeta;
}

}

然后我的配置類

@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

UserSessionInterceptor userSessionInterceptor;

@Autowired
public AppConfig(UserSessionInterceptor userSessionInterceptor) {
    this.userSessionInterceptor = userSessionInterceptor;
}

@Bean
@RequestScope
public HWRequest hwRequest() {
    return new HWRequest();
}

@Bean
public UserSessionInterceptor createUserSessionInterceptor() {
    return userSessionInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(createUserSessionInterceptor()).addPathPatterns("/user/**");
}
}

這是我修改的攔截器

@Component
@ControllerAdvice
public class SessionInterceptor implements AsyncHandlerInterceptor {

@Resource
HWRequest hwRequest;

...

@ModelAttribute
public HWRequest getTest() {
    return this.hwRequest;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {

...

// parse the key from the request

... 

MetaMagicKey metaMagicKey = metaMagicKeyRepo.findKeyByMagicKey(key);

// do work here query my DB and build stuff

...

// assign the queried data built into object
this.hwRequest.setMyMeta(metaMagicKey.getId().getMyMeta());

return true;
}

當然還有適合我需要的修改過的控制器

@Controller
@RequestMapping("/user")
public class WebAppUserController {

@RequestMapping(value = "/home/{authKey}",method = RequestMethod.GET)
String index(@ModelAttribute HWRequest request, Model model){

    return "index";
}

@RequestMapping(value = "/config/{authKey}",method = RequestMethod.GET)
String config(@ModelAttribute HWRequest request, Model model){

    return "configure";
}

}

基於我讀過的所有文檔,這應該可以工作,但也許我錯過了一些東西,因為攔截器仍然是一個單身人士。 也許我錯過了什么?

myMeta變量表示單例 bean 中的狀態。 當然它不是線程安全的,各種用戶都會發生沖突。 永遠不要將任何應用程序狀態存儲在單例 bean 中。

如果您想為每個請求存儲一些狀態,請使用 Spring 的請求范圍。 這意味着創建單獨的 bean 僅用於存儲用@RequestScope注釋注釋的狀態

對編輯的反應:

這個 bean 注冊可以被刪除,因為它已經用@Component注解注冊到 Spring IoC 容器中:

@Bean
@RequestScope
public HWRequest hwRequest() {
    return new HWRequest();
}

AppConfig 中不需要的另一部分是自動裝配UserSessionInterceptor bean 並將其再次注冊為 bean。 刪除那個。 由於該 bean 正在自動裝配,它顯然已經在 IoC 容器中,因此無需再次注冊它。

另一個令人困惑的部分是命名中的工作session 當您處理@RequestScope而不是@SessionScope我建議將您的類的命名更改為request (例如RequestInterceptor )。 Session 和 Request 是非常不同的野獸。

否則它看起來可以工作並且應該是線程安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM