Java Struts 2+;Spring在会话中放置了一个托管Springbean

Java Struts 2+;Spring在会话中放置了一个托管Springbean,java,spring,spring-mvc,session,struts2,Java,Spring,Spring Mvc,Session,Struts2,考虑Struts 2+Spring 4项目 对于每个登录,用户对象都被置于会话中。作为一个非常简单的动作,它看起来 public class LoginProcess implements ServletRequestAware { @Inject private AuthenticationServices authenticationServices; public String execute() { //The login method makes a new U

考虑Struts 2+Spring 4项目

对于每个登录,
用户
对象都被置于会话中。作为一个非常简单的动作,它看起来

public class LoginProcess implements ServletRequestAware {

  @Inject
  private AuthenticationServices authenticationServices;

  public String execute() {
    //The login method makes a new User and fills its setters
    User newUser = authenticationServices.login(....);
    getServletRequest().getSession().setAttribute("USER_SESSION", user);
  }
}
由于我们手动创建了一个新的
User
对象,因此它不是受管理的Springbean,并且我们不能在
User
类中使用spring特性:
@Inject
@Value

我尝试将用户更改为:

@Named
@Scope(value="session")
public class User { ...
    @Inject
    private AccountServices accountServices;

}
并将
用户
插入,而不是调用
新用户
,但我得到错误:

Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at org.springframework.web.context.request.SessionScope.get(SessionScope.java:91)
虽然它描述了错误,但我找不到如何修复它,我也不确定这是否是正确的方法。似乎我在使用spring mvc时只能使用spring
session scope
been

有什么评论吗


我为什么需要这个?!(简化的情况)

用户对象有一个获取所有用户帐户的
getAccounts()
方法。获取用户帐户是一项昂贵的操作,用户登录时可能不需要其帐户

因此,我们不让get方法在用户登录时立即获取用户帐户,而是让get方法在没有用户帐户时获取用户帐户:

public class User() {
  private Accounts accounts;

  @Inject
  private AccountServices accountServices;

  Accounts getAccounts() {
    if (accounts == null) {
      accounts = accountServices.getUserAccountsFromDB(...)
    }
    return accounts;
  }

不要自己创建
User
的新实例,而是从Spring上下文获取bean

例如,您可以通过实现
ApplicationContextAware
接口并调用
getBean
方法之一来实现它

User user = applicationContext.getBean(User.class);
// populate user and put it into session
这样,它就是一个Spring管理的bean,应该注入所有必需的属性


但请考虑将您的<代码>用户<代码>更改为简单的POJO,并将所有业务逻辑(例如,将用户帐户获取)移到更合适的位置,这样您的模型层将更为干净和易于测试。在<代码>用户< /代码>中,有什么好的理由,比如<代码> ActudioServices <代码>?将您的

User
对象更改为simple pojo。是否有充分的理由继续使用Spring而不是CDI?@AleksandrM我已更新我的问题以解决此问题@AndreaLigios我们使用spring不仅是为了它的DI注入(可以被CDI替代),而且是为了其他spring特性和项目,这些特性和项目对我们帮助很大。@AlirezaFattahi IKR,我经常使用spring并且非常喜欢它,然后我发现了带有JPA2、CDI、EJB3.x的JavaEE6+。我不会回去喝茶。只是一个提示:要访问
应用程序上下文
,我使用了
@Inject-private-application-context-appContextappContext.getBean(User.class)