我有UsersHandledInRequestCache
bean,用于在请求期间缓存:
@Configuration
public class CacheConfiguration {
@Bean
@RequestScope
public UsersHandledInRequestCache usersHandledInRequestCache() {
return new UsersHandledInRequestCache();
}
public static class UsersHandledInRequestCache {
private final Set<Integer> cachedUsersIds = new HashSet<>();
public void cache(Integer userId) {
this.cachedUsersIds.add(userId);
}
public boolean isCached(Integer userId) {
return this.cachedUsersIds.contains(userId);
}
}
}
字符串
我有一个使用bean的服务:
@Service
public class UserService {
@Resource(name = "usersHandledInRequestCache")
private CacheConfiguration.UsersHandledInRequestCache usersHandledInRequestCache;
public void doSomething(Integer userId) {
if (!usersHandledInRequestCache.isCached(userId)) {
// do something
usersHandledInRequestCache.cache(userId);
}
}
}
型
所以服务可以由控制器调用,没有问题:
@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@PostMapping
public void doSomething(@RequestBody Collection<Integer> usersIds) {
usersIds.forEach(userService::doSomething);
}
}
型
在本例中,UsersHandledInRequestCache
bean为每个请求创建并且工作正常。但是我有预定的服务:
@Component
@RequiredArgsConstructor
public class UserJob {
private final UserService userService;
@Scheduled(cron = "0 0 7 * * *")
public void doSomething() {
userService.getSomeUsersIds.forEach(userService::doSomething);
}
}
型
而当调度服务开始工作时,我得到异常,因为字段UserService#usersHandledInRequestCache
无法初始化 (因为没有任何请求,方法调用是由调度服务工作发起的):
创建名为“scopedTarget. usersHandledInRequestCache”的bean时出错:作用域“请求”对于当前线程不是活动的;如果您打算从单例引用这个bean,请考虑为它定义一个作用域代理;嵌套异常为java.lang.IllegalStateException:未找到线程绑定请求:你指的是实际Web请求之外的请求属性,还是在原始接收线程之外处理请求?如果你实际上是在一个web请求中操作,并且仍然收到这个消息,那么你的代码可能是在DispatcherServlet之外运行的:在这种情况下,使用RequestContextListener或RequestContextFilter公开当前请求。
我想让bean UsersHandledInRequestCache
同时具有“request”作用域和“schedule”作用域。我怎么能得到它?
1条答案
按热度按时间pieyvz9o1#
因为spring请求范围只注册了web应用请求,所以出现上述错误。
通过
RequestAttribute
接口的实现,spring从HttpRequest中放入/获取请求范围信息。如果线程是在Web请求之外启动的,则线程的变量中没有所需的属性,因此会引发异常。
我遇到了同样的问题-需要使用
@Scheduled
执行作业中的代码,因此它无法使用任何Session或Request作用域bean。有几种方法可以解决这个问题,我用下面的方法解决了它:
实现RequestAttributes接口:
字符串
现在,在代码中请求的开始,通过执行以下语句指示
RequestContextHolder
使用此CustomRequestAttribute
,并在finally块中清除请求属性。型