在没有try-catch的情况下检查Spring代理bean的状态有效性

时间:2012-08-17 18:53:05

标签: spring spring-mvc proxy-classes

我有一个由以下类的服务创建的bean:

@Configuration
public class AccessManager {

    @Bean(name="access", destroyMethod="destroy")
    @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    @Autowired
    public Access create(HttpServletRequest request) {
        System.out.println(request.getRemoteAddr());
        return new Access();
    }

}

一切都按预期工作,除了当应用程序启动时,正在调用此方法,可能是因为我有一些使用Access bean的其他单例bean。在启动时没有绑定到Thread的请求,并且在尝试访问java.lang.IllegalStateException参数的任何属性时,它应该会得到request

没问题。 问题是,是否可以检查代理 HttpServletRequest 的基础 request 是否在调用引发异常的属性之前null

2 个答案:

答案 0 :(得分:2)

您可能想看看RequestContextHolder#getRequestAttributes()。如果您当前不在可以使用请求范围的上下文中,那么将返回null

@Configuration
public class AccessManager {

    @Bean(name="access", destroyMethod="destroy")
    @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    @Autowired
    public Access create(HttpServletRequest request) {
        if (RequestContextHolder.getRequestAttributes() != null) {
            System.out.println(request.getRemoteAddr());
        }
        return new Access();
    }

}

答案 1 :(得分:1)

我认为这里的问题是关注点分离。通常,您的服务层不应该对servlet类有任何依赖性。这非常关注控制器/ UI。

应为您的服务类提供完成工作所需的属性。在这种情况下是一个String。应该从一个用servlet请求注入的控制器方法调用这个服务方法。

如下所示:

@Controller
public class MyController {

  @Autowired
  private AccessManager accessManager;


  @RequestMapping
  public void handleRequest(HttpServletRequest request) {
    accessManager.create(request.getRemoteAddr());
  }
}

,您的服务将如下所示:

@Service
public class AccessManager {

  public Access create(String remoteAddress) {
    return new Access();
  }
}

总而言之,注释为@Service的任何内容都不应该有权访问请求。