【问题标题】:Spring @Autowired gives new instance instead of initialized session scoped beanSpring @Autowired 提供新实例而不是初始化的会话范围 bean
【发布时间】:2017-03-13 18:50:43
【问题描述】:

我正在使用 Spring 开发应用程序,我需要在会话中初始化 Ticket 对象,然后从另一个控制器获取它。

我有两个控制器,所以有两个 xml 上下文。

web.xml

    <web-app id="WebApp_ID" version="2.4"
   xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

   <display-name>Spring Web MVC Application</display-name>

   <welcome-file-list>
      <welcome-file>index.html</welcome-file>
   </welcome-file-list>

   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring-context.xml</param-value>
   </context-param>

   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <servlet>
      <servlet-name>rest</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/rest-context.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>rest</servlet-name>
      <url-pattern>/rest/*</url-pattern>
   </servlet-mapping>

   <servlet>
      <servlet-name>index</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/index-context.xml</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>index</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>

rest-context.xml

<beans ...>
    <mvc:annotation-driven/>    
    <context:annotation-config/>    
    <context:component-scan base-package="menu.MenuController"/>    
</beans>

index-context.xml

<beans ...>
    <mvc:annotation-driven/>
    <mvc:resources mapping="/**" location="/"/>

    <context:annotation-config/>    
    <bean class="auth.IndexWebController" />    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>

在 spring-context 中,我有我的 Ticket bean:

<bean id="tickerProvider" class="TicketProviderImpl" scope="session">
    <aop:scoped-proxy/>

和其他豆子一起。

这是我的控制器的样子:

IndexWebController.java

@Controller
@SessionAttributes("user")
public class IndexWebController {

    private static Logger logger = LoggerFactory.getLogger(IndexWebController.class);

    @Autowired
    private TicketProviderImpl ticketProvider;

    @ModelAttribute("user")
    public User populateUser() {
        return new User();
    }

    @RequestMapping(value = "/", method = {RequestMethod.POST, RequestMethod.GET})
    public ModelAndView printIndex(@ModelAttribute("user") User user,
                                   @RequestParam(value = "iv-user", required = false) String login,
                                   @RequestParam(value = "iv-groups", required = false) String groups) {
        ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("index.html");

<...>            
        ticketProvider.setLogin(login);
                logger.info("Пользователь установлен в " + login);
    <...>

MenuController.java

@Controller
public class MenuController {

    @Autowired
    private TicketProviderImpl ticketProvider;

    @ResponseBody
    @RequestMapping("/getMenuList")
    public MenuListDTO getMenuList(


             @RequestParam(value = "menuId", required = true, defaultValue = "-1") long menuId,
                @RequestParam(value = "parentId", required = true, defaultValue = "0") long parentId) {

<...>
            System.out.println(ticketProvider.getLogin());
<...>

        }
    }

问题是,当我在 MenuController 中自动装配 ticketProvider bean 时,我得到了它的一个新实例,而不是那些已在 IndexWebController 中初始化的实例。实际上我得到了空值,但正在等待登录。

使用 session scoped beans 的错误或误解在哪里?

【问题讨论】:

    标签: java spring autowired


    【解决方案1】:

    根据this,您将需要另一个侦听器来将您的会话公开给应用程序。 因此添加 &lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt; 应该可以解决问题。

    【讨论】:

    • 我想知道,你解决了这个问题吗?我的回答被否决了,我很好奇为什么? @Andrey Z。
    猜你喜欢
    • 1970-01-01
    • 2013-12-30
    • 2013-05-22
    • 1970-01-01
    • 2012-11-03
    • 2011-12-19
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多