将请求范围的 bean 注入另一个 bean
Inject request scoped bean into another bean
我想创建一个在请求生命周期中唯一的 UUID。
为此,我使用 @Scope("request") 注释创建了一个 UUID bean。
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
public UUID requestUUID() {
return UUID.randomUUID();
}
我想在我的控制器中访问这个 bean。所以我用@Autowired注入它。
这很好用。
@Controller
public class DashboardController {
@Autowired
UUID uuid;
@Autowired
WelcomeMessageService welcomeMessageService;
@Autowired
IssueNotificationService issueNotificationService;
@RequestMapping("/")
public String index(Model model) throws InterruptedException, ExecutionException {
System.out.println(uuid);
PortalUserDetails userLog = getPortalUserDetails();
BusinessObjectCollection<WelcomeMessage> welcomeMessages = welcomeMessageService.findWelcomeMessages(
20,
0,
userLog.getZenithUser(),
userLog.getConnectionGroup().getConnectionGroupCode(),
"FR");
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
BusinessObjectCollection<IssueNotification> issueNotifications =
issueNotificationService.findIssueNotifications(userLog.getZenithUser());
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
model.addAttribute("issueNotifications", issueNotifications);
return "index";
}
}
控制器调用多个服务。每个服务都使用一个 RestTemplate bean。在这个 RestTemplate bean 中,我想获取 UUID。
@Component
public class ZenithRestTemplate extends RestTemplate {
@Autowired
private UUID uuid;
public void buildRestTemplate() {
List restTemplateInterceptors = new ArrayList();
restTemplateInterceptors.add(new HeaderHttpRequestInterceptor("UUID", uuid.toString()));
this.setInterceptors(restTemplateInterceptors);
}
}
当我尝试在此处注入 UUID 时,出现错误:
Error creating bean with name 'zenithRestTemplate': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.UUID com.geodis.rt.zenith.framework.webui.service.ZenithRestTemplate.uuid; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestUUID': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is 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.
如何访问 RestTemplate bean 中的 UUID bean?
我的项目使用 Spring-MVC,Spring-boot java 配置。
我已经尝试添加 RequestContextListener,但它没有解决问题。
@Bean public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
我认为您需要将 UUID
请求作用域 bean 标记为:
@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
控制器是 singleton
作用域 bean,您正在其中注入 request
作用域 bean。由于单例 bean 在其生命周期内仅注入一次,因此您需要提供作用域 bean 作为代理来处理这一点。
另一种选择是使用 org.springframework.web.context.annotation.RequestScope
注释:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_REQUEST)
public @interface RequestScope {
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
@RequestScope
是 @Scope
上的元注释 1) 将 scope
设置为 "request"
和 2) 将 proxyMode
设置为 ScopedProxyMode.TARGET_CLASS
这样您就不必在每次要定义请求范围的 bean 时都这样做。
编辑:
请注意,您可能需要在主配置 class 上添加 @EnableAspectJAutoProxy
。
我想创建一个在请求生命周期中唯一的 UUID。 为此,我使用 @Scope("request") 注释创建了一个 UUID bean。
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
public UUID requestUUID() {
return UUID.randomUUID();
}
我想在我的控制器中访问这个 bean。所以我用@Autowired注入它。 这很好用。
@Controller
public class DashboardController {
@Autowired
UUID uuid;
@Autowired
WelcomeMessageService welcomeMessageService;
@Autowired
IssueNotificationService issueNotificationService;
@RequestMapping("/")
public String index(Model model) throws InterruptedException, ExecutionException {
System.out.println(uuid);
PortalUserDetails userLog = getPortalUserDetails();
BusinessObjectCollection<WelcomeMessage> welcomeMessages = welcomeMessageService.findWelcomeMessages(
20,
0,
userLog.getZenithUser(),
userLog.getConnectionGroup().getConnectionGroupCode(),
"FR");
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
BusinessObjectCollection<IssueNotification> issueNotifications =
issueNotificationService.findIssueNotifications(userLog.getZenithUser());
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
model.addAttribute("issueNotifications", issueNotifications);
return "index";
}
}
控制器调用多个服务。每个服务都使用一个 RestTemplate bean。在这个 RestTemplate bean 中,我想获取 UUID。
@Component
public class ZenithRestTemplate extends RestTemplate {
@Autowired
private UUID uuid;
public void buildRestTemplate() {
List restTemplateInterceptors = new ArrayList();
restTemplateInterceptors.add(new HeaderHttpRequestInterceptor("UUID", uuid.toString()));
this.setInterceptors(restTemplateInterceptors);
}
}
当我尝试在此处注入 UUID 时,出现错误:
Error creating bean with name 'zenithRestTemplate': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.UUID com.geodis.rt.zenith.framework.webui.service.ZenithRestTemplate.uuid; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestUUID': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is 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.
如何访问 RestTemplate bean 中的 UUID bean?
我的项目使用 Spring-MVC,Spring-boot java 配置。
我已经尝试添加 RequestContextListener,但它没有解决问题。
@Bean public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
我认为您需要将 UUID
请求作用域 bean 标记为:
@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
控制器是 singleton
作用域 bean,您正在其中注入 request
作用域 bean。由于单例 bean 在其生命周期内仅注入一次,因此您需要提供作用域 bean 作为代理来处理这一点。
另一种选择是使用 org.springframework.web.context.annotation.RequestScope
注释:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_REQUEST)
public @interface RequestScope {
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
@RequestScope
是 @Scope
上的元注释 1) 将 scope
设置为 "request"
和 2) 将 proxyMode
设置为 ScopedProxyMode.TARGET_CLASS
这样您就不必在每次要定义请求范围的 bean 时都这样做。
编辑:
请注意,您可能需要在主配置 class 上添加 @EnableAspectJAutoProxy
。