2011-02-18 30 views
2

由於缺乏Spring知識,我對scope bean的依賴關係有些疑問。Spring MVC Scoped Bean依賴性和競爭條件

我已閱讀參考手冊3.5.4.5作爲依賴關係的範圍bean,併成功實現了一個關於它的示例。

但是在再進一步之前,我想分享我的擔憂。

讓我分享我的使用情況和小的實現細節

對於每個用戶的請求,我想創造一個城市的每個用戶。

@Configuration 
public class CityFactory{ 

    @Bean(name = {"currentCity" , "loggedInCity"}) 
    @Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.TARGET_CLASS) 
    @Autowired 
    public CityBean getCityBean(HttpServletRequest request) { 
     return CityUtil.findCityWithHostName(request.getServerName()); 
    } 

因爲我想這個城市注入到一個單獨的每個請求範圍控制器,它是控制器的默認範圍。

@RequestMapping("/demo") 
@Controller 
public class DemoController { 

    @Autowired 
    CityBean city; 

    @RequestMapping(value = "/hello/{name}", method = RequestMethod.GET) 
    public ModelAndView helloWorld(@PathVariable("name") String name, Model model) { 
     Map<String, Object> myModel = new HashMap<String, Object>(); 
     model.addAttribute("hello", name); 
     model.addAttribute("test", "test in " + city.getDomainName() + " !!! "); 

     return new ModelAndView("v3/test", "m", model); 
    } 
} 

我的問題:

1)是否有任何競爭條件?我擔心上下文切換會在多請求環境中破壞我的應用程序。

2)我知道另一種解決方案,它爲每個請求創建一個控制器,但它比當前的解決方案更容易出錯。因爲另一個開發人員可能會忘記範圍控制器提出請求。

如何讓控制器在全局範圍內請求範圍?只是因爲有點好奇。

謝謝...

回答

0

沒有競爭條件 - 每個請求都有自己的線程

但我認爲有一個更簡單的方法做你想做的。你可以有你CityBean

@Service 
public class CityBean { 
    public String getDomainName(String serverName) { 
     // obtain the name based on the server name 
    } 
} 

而在你的控制器:

  • @Autowired CityBean bean
  • HttpServletRequest作爲參數的方法,並調用cityBean.getDomainName(request.getServerName());

(如果你使用一些ORM,也許你會有一個City實體,你可以獲取並傳遞,只是提防懶惰集合)

+0

CityBean類來自另一個遺留圖書館。非常感謝您的建議。 – Ozgur 2011-02-18 11:04:17

0

這裏沒有競賽條件。

這是範圍代理點 - 的CityBean注入DemoController實例是一個代理,並代理其方法的CityBean實際要求結合實例的呼叫,這樣,每個請求的工作與自己的CityBean

我同意你不應該讓控制器本身的請求範圍 - 這會讓其他人感到困惑,因爲它不是Spring MVC應用程序中的典型方法。

您也可以按照Bozho建議的方法去除請求範圍的bean,儘管這種方法有一個缺點,因爲它要求您向控制器方法中添加額外的參數。