将请求范围的bean注入另一个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 welcomeMessages = welcomeMessageService.findWelcomeMessages( 20, 0, userLog.getZenithUser(), userLog.getConnectionGroup().getConnectionGroupCode(), "FR"); if(welcomeMessages!=null) { model.addAttribute("welcomeMessages", welcomeMessages.getItems()); } BusinessObjectCollection 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时,我有一个错误:

创建名为’zenithRestTemplate’的bean时出错:注入自动连接的依赖项失败; 嵌套exception是org.springframework.beans.factory.BeanCreationException:无法自动assembly字段:private java.util.UUID com.geodis.rt.zenith.framework.webui.service.ZenithRestTemplate.uuid; 嵌套exception是org.springframework.beans.factory.BeanCreationException:创建名为’requestUUID’的bean时出错:当前线程的作用域’request’无效; 考虑为这个bean定义一个范围代理,如果你打算从一个单例引用它; 嵌套exception是java.lang.IllegalStateException:找不到线程绑定请求:您是指实际Web请求之外的请求属性,还是处理最初接收线程之外的请求? 如果您实际在Web请求中操作并仍然收到此消息,则您的代码可能在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter来公开当前请求。

如何在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每生命只注入一次,因此您需要提供作用域的代理来处理它。

另一种选择是使用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)将ScopedProxyMode.TARGET_CLASS设置为ScopedProxyMode.TARGET_CLASS这样每次要定义请求范围的bean时都不必这样做。

编辑:

请注意,您可能需要在主配置类上添加@EnableAspectJAutoProxy