如何正确使用会话范围的bean

时间:2014-03-17 16:19:07

标签: java session spring-mvc spring-aop

我的Spring MVC应用程序中有3个类:UserDetailsInterceptor类,MyAdvice类和UserDetails类(会话作用域)。

我想要完成的事情很简单:

  1. UserDetailsInterceptor拦截请求并在会话作用域UserDetails bean中设置用户ID。
  2. 稍后,当调用AOP通知类中的方法时,从会话作用域UserDetails bean中检索用户的id。
  3. 问题(也在下面的代码中标明):

    1. UserDetails对象在MyAdvice类中为空。
    2. UserDetailsInterceptor中,userDetails.setUserID(request.getRemoteUser());不执行任何操作。
    3. 代码

      UserDetailsInterceptor上课:

      public class UserDetailsInterceptor extends HandlerInterceptorAdapter {
      
          @Autowired
          private UserDetails userDetails;
      
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              //set user ID, but next line doesn't do anything for some reason (e.g. `userID` is still null)
              userDetails.setUserID(request.getRemoteUser());
              return true;
          }
      }
      

      MyAdvice上课:

      public class MyAdvice implements MethodInterceptor {
      
          @Autowired
          private UserDetails userDetails; //It's null
      
          @Override
          public Object invoke(MethodInvocation invocation) throws Throwable {
              //Print user ID
              System.out.println(userDetails.getID());
              return invocation.proceed();
          }
      }
      

      UserDetails上课:

      public class UserDetails {
      
          private String userID;
      
          public void setUserID(String userID) {
              this.userID= userID;
          }
      
          public String getUserID() {
              return this.userID;
          }
      }
      

      dispatcher-servlet.xml

      <bean id="userDetails " class="package.UserDetails " scope="session">
          <aop:scoped-proxy/>
      </bean>
      

      MyPointcutAdvisor上课:

      public class MyPointcutAdvisor implements PointcutAdvisor {
      
          private MyPointcut pointcut = new MyPointcut();
          private MyAdvice advice = new MyAdvice();
      
          @Override
          public Pointcut getPointcut() {
              return this.pointcut;
          }
      
          @Override
          public Advice getAdvice() {
              return this.advice;
          }
      
          @Override
          public boolean isPerInstance() {
              return false;
          }
      }
      

      有什么想法吗?提前谢谢。

      更新

      通过注册MyAdvice类,其中的userDetails对象不再为空。但它与UserDetailsInterceptor中的对象不同。那么bean实际上并不是“会话范围”?

      答案

      问题在于以下代码:

      private MyPointcut pointcut = new MyPointcut();
      private MyAdvice advice = new MyAdvice();
      

      它们都不是由春天管理的。结果,事情正在被连线,而不是按照我们的预期运作。

1 个答案:

答案 0 :(得分:1)

  

UserDetails对象在null类中为MyAdvice

如果MyAdvice实例由Spring管理,则

是不可能的。您必须自己实例化它,而不是从上下文中获取它。

如果Spring无法管理对象,则无法向@Autowired目标中注入任何内容,因此您的字段仍为null

如果Spring管理你的对象,一个bean,并且无法解决依赖关系,那么就会抛出异常。