2011-02-18 2 views
2

У меня есть некоторые серьезные сомнения относительно зависимостей бобов в боковом свете из-за отсутствия знаний о весне.Spring MVC Scope Bean Dependencies and Race Conditions

Я прочитал справочное руководство в разделе 3.5.4.5. Скованные бобы в качестве зависимостей и успешно выполнили пример.

Однако, прежде чем идти дальше, я хотел поделиться своими проблемами.

Позвольте мне поделиться случай использования и мелкие детали реализации

Для каждого запроса пользователя, я хотел бы создать город для каждого пользователя.

@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

0

Здесь нет условий гонки.

Это точка контекстными прокси - экземпляр CityBean впрыскивается в DemoController является прокси, который делегирует вызовы своего метода к реальному запросу переплета экземпляру CityBean, так что каждый запрос работает со своим собственным CityBean.

Я согласен с тем, что вы не должны делать сам контроллер с запросом - он будет запутан для других людей, поскольку это не типичный подход в Spring MVC-приложениях.

Вы также можете следовать предложенному Бозо и предлагать возможность избавиться от боба с запросом, хотя этот подход имеет недостаток, поскольку для этого требуется добавить дополнительный аргумент в методы вашего контроллера.