source

요청 범위 빈을 다른 빈에 주입합니다.

factcode 2023. 7. 8. 11:14
반응형

요청 범위 빈을 다른 빈에 주입합니다.

요청 수명 주기에서 고유한 UUID를 생성하려고 합니다.이를 위해 @Scope("request") 주석이 있는 UUID 빈을 만듭니다.

@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
public UUID requestUUID() {
    return UUID.randomUUID();
}

컨트롤러에 있는 이 빈에 액세스하고 싶습니다.그래서 저는 그것을 @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 빈에서 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'인 빈을 만드는 동안 오류가 발생했습니다.자동 배선 종속성을 주입하지 못했습니다. 중첩 예외는 org.springframework입니다.콩 공장콩 창조예외:개인 java.util 필드를 자동 배선할 수 없습니다.UUID com.geodis.rt.zenith.framework.webui.service.제니스 레스트 템플릿.uuid; 중첩된 예외는 org.springframework입니다.콩 공장콩 창조예외:이름이 'request'인 빈을 만드는 동안 오류가 발생했습니다.UUID': 범위 'request'가 현재 스레드에 대해 활성화되지 않았습니다. 싱글톤에서 이 빈을 참조하려면 범위가 지정된 프록시를 정의하십시오. 중첩된 예외는 java.lang입니다.잘못된 상태 예외:스레드 바인딩된 요청을 찾을 수 없습니다.실제 웹 요청 외부의 요청 속성을 말하는 것입니까, 아니면 원래 수신 스레드 외부의 요청을 처리하는 것입니까?실제로 웹 요청 내에서 작업 중이고 여전히 이 메시지가 표시되는 경우 코드가 DispatcherServlet/DispatcherPortlet 외부에서 실행되고 있을 수 있습니다.이 경우 RequestContextListener 또는 RequestContextFilter를 사용하여 현재 요청을 표시합니다.

RestTemplate bean 내 UUID bean에 액세스하려면 어떻게 해야 합니까?

제 프로젝트는 Java 구성이 있는 Spring-MVC, Spring-boot을 사용합니다.

이미 RequestContextListener를 추가하려고 했지만 문제가 해결되지 않습니다.

@Bean public RequestContextListener requestContextListener(){
    return new RequestContextListener();
}

제 생각에 당신은 당신의 것을 표시할 필요가 있습니다.UUID요청 범위 빈:

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

컨트롤러 위치singleton당신이 주입하고 있는 스코프 빈request그 안에 들어 있는 스코페 빈싱글톤 원두는 평생에 한 번만 주입되기 때문에 스코프 원두를 대용품으로 제공하면 됩니다.

또 다른 옵션은 대신 다음을 사용하는 것입니다.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 분다니입석annot타에 있는 메타 입니다.@Scope그것 1)이 설정합니다.scope"request"및 2) 다음을 설정합니다.proxyModeScopedProxyMode.TARGET_CLASS따라서 요청 범위 빈을 정의할 때마다 이 작업을 수행할 필요가 없습니다.

편집:

있니다습을 추가해야 할 .@EnableAspectJAutoProxy기본 구성 클래스에 있습니다.

언급URL : https://stackoverflow.com/questions/34090750/inject-request-scoped-bean-into-another-bean

반응형