当前位置:  开发笔记 > 编程语言 > 正文

将请求范围的bean注入另一个bean

如何解决《将请求范围的bean注入另一个bean》经验,为你挑选了1个好方法。

我想创建一个在请求生命周期中唯一的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时出错:注入自动连接的依赖项失败; 嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private java.util.UUID com.geodis.rt.zenith.framework.webui.service.ZenithRestTemplate.uuid; 嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'requestUUID'的bean时出错:当前线程的作用域'request'无效; 考虑为这个bean定义一个范围代理,如果你想从一个单例引用它; 嵌套异常是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();
}

Jan Zyka.. 18

我认为您需要标记您的UUID请求范围bean,如:

@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)

控制器是singletonscoped bean,你在其中注入requestscoped 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是一个元注释@Scope1)设置scopeto "request"和2)设置proxyModeto,ScopedProxyMode.TARGET_CLASS所以你不必每次想要定义一个请求范围的bean时都这样做.

编辑:

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



1> Jan Zyka..:

我认为您需要标记您的UUID请求范围bean,如:

@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)

控制器是singletonscoped bean,你在其中注入requestscoped 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是一个元注释@Scope1)设置scopeto "request"和2)设置proxyModeto,ScopedProxyMode.TARGET_CLASS所以你不必每次想要定义一个请求范围的bean时都这样做.

编辑:

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

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有