【问题标题】:Accessing a session-scoped bean inside a controller访问控制器内的会话范围 bean
【发布时间】:2017-09-10 04:12:51
【问题描述】:

我正在 Spring 3 中试验会话范围的 bean。我有以下 bean 定义:

<bean id="userInfo" class="net.sandbox.sessionbeans.UserInfo" scope="session" />

这里是net.sandbox.controllers.RegistrationController,一个需要访问这个bean 的控制器类。为了简洁起见,我已经删除了导入。

@Controller
@RequestMapping("/register")
public class RegistrationController {
    private UserInfo userInfo;   // This should reference the session-scoped bean

    @RequestMapping(method = RequestMethod.GET)
    public String showRegForm(Model model) {
        RegistrationForm regForm = new RegistrationForm();
        model.addAttribute("regform", regForm);
        return "regform";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String validateForm(@Valid RegistrationForm regForm, BindingResult result, Model model) {
        if (result.hasErrors()) {
            return "regform";
        }

        userInfo.setUserName(regForm.getFirstName());
        model.addAttribute("regform", regForm);
        return "regsuccess";
    }
}

有没有办法自动将我定义的会话范围的bean绑定到RegistrationController中的成员变量private UserInfo userInfo?

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    是的 - 请参阅section 3.4.5.4 of the Spring manual, "Scoped beans as dependencies"。

    简单地说,您可以要求 Spring 将您的会话范围 bean 包装在一个单例代理中,当您在范围 bean 上调用方法时,该代理会查找正确的会话。这称为“范围代理”,并使用 &lt;aop:scoped-proxy&gt; 配置宏。然后,您可以像其他任何方式一样注入引用(例如 &lt;property&gt; 或 @Autowired)。详情见以上链接。

    【讨论】:

    • 我尝试应用这种技术。我将&lt;aop:scoped-proxy /&gt; 放在bean 定义中,然后@Autowired'd private UserInfo userInfo。它似乎可以工作,但由于某种原因,bean 的 setter 函数没有正确执行......i.imgur.com/zkxVA.png
    • @Pieter 以上有什么进展吗?我也面临同样的问题
    • @Sudarshan 我不久前将这个网站作为短期学校项目的一部分,我不再致力于它。对不起!祝你好运找到解决方案。
    【解决方案2】:

    默认情况下,Spring 通过在运行时实现接口来创建代理。因此,代理上唯一可用的方法是在 UserInfo 实现的任何接口中定义的方法(如果有的话)。您可能必须创建一个包含 setUserName() 方法的合适接口。

    或者,您需要强制使用基于 CGI 的代理(代理是在运行时创建的类的子类,因此它不需要接口)。指定:

    <bean id="userInfo" class="net.sandbox.sessionbeans.UserInfo" scope="session" >
       <aop:scoped-proxy proxy-target-class="true"/>
    </bean>
    

    【讨论】:

      【解决方案3】:

      关于此评论:

      我尝试应用这种技术。我放 豆内 定义和我@Autowired'd private 用户信息用户信息。它似乎工作, 但由于某种原因,bean的设置器 功能未正确执行... i.imgur.com/zkxVA.png – 彼得 1 小时 以前

      如果您使用基于接口的代理,除非接口具有 setter 方法,否则 setter 方法在 Proxy 上不可用。

      【讨论】:

      • 基于接口的代理?我是 Spring、Java Web 开发和设计模式的新手,所以恐怕我不知道您在描述什么。我只知道我想访问和更新该控制器类中的“userInfo”bean。如果这没有帮助,我深表歉意。 :)
      【解决方案4】:

      如果你不喜欢 XML,你也可以像这样使用ObjectFactory&lt;T&gt;:

      @RestController
      public class MyController {
          private final ObjectFactory<MySessionScopedComponent> OFSession;
      
          @Autowired
          public MyController(ObjectFactory<MySessionScopedComponent> OFSession) {
              this.OFSession = OFSession;
          }
      
          @RequestMapping(path = "/path", method = RequestMethod.GET)
          public String myMethod () {
              MySessionScopedComponent sessionBean = OFSession.getObject();
              // Do some stuff
              return bean.myValue();
          }
      }
      

      注意:使用 Spring Boot 1.5.6 (Spring 4.3) 测试

      【讨论】:

        猜你喜欢
        • 2012-05-26
        • 1970-01-01
        • 2012-01-20
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 2015-09-13
        • 1970-01-01
        • 2013-01-05
        相关资源
        最近更新 更多