我有一个由以下类的服务创建的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
?
答案 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的任何内容都不应该有权访问请求。