【问题标题】:Qualifier for Bean dont found name in @Service constructor在 @Service 构造函数中找不到 Bean 的限定符
【发布时间】:2022-02-01 12:44:59
【问题描述】:

我正在尝试调用一种方法来使用 OAuth2RestTemplate 设置其余模板值,我在项目的其他部分创建了一个配置文件(项目的核心部分和应用程序部分,它们之间没有依赖关系)具有OAuth2RestTemplate 的 bean:

public class RestTemplateConfig {

    @Bean(name = "oAuth2RestTemplateMbDev")
    public OAuth2RestTemplate oAuth2RestTemplate(MbdevOAuth2Properties resource, Proxy proxy) {
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource);
        ClientHttpRequestFactory requestFactory = getRequestFactory(proxy);

        restTemplate.setAccessTokenProvider(getAccessTokenProvider(requestFactory));
        restTemplate.setRequestFactory(requestFactory);
        restTemplate.setErrorHandler(new MbdevResponseErrorHandler());
        restTemplate.getInterceptors().add(new MbdevHeadersInterceptor());

        return restTemplate;
    }

    @Bean(name = "oAuth2RestTemplate")
    public OAuth2RestTemplate oAuth2RestTemplate(NexnetOAuth2Properties resource, Proxy proxy) {
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource);
        ClientHttpRequestFactory requestFactory = getRequestFactory(proxy);

        restTemplate.setAccessTokenProvider(getAccessTokenProvider(requestFactory));
        restTemplate.setRequestFactory(requestFactory);
        restTemplate.setErrorHandler(new NexnetResponseErrorHandler());
        restTemplate.getInterceptors().add(new NexnetHeadersInterceptor());

        return restTemplate;
    }
}

这是我创建的,另一个已经存在:

@Bean(name = "oAuth2RestTemplateMbDev")
public OAuth2RestTemplate oAuth2RestTemplate(MbdevOAuth2Properties resource, Proxy proxy)

所以为了能够为同一个类使用 2 个 Bean,我分配了一个名称以使用 @Qualifier 调用。

像这样:

@Slf4j
@Service
@ConditionalOnProperty(name = "feature.toggles.value", havingValue = "true", matchIfMissing = true)
public class MBdevOrderApiDataService implements OrderItemApiData {

    private URI resource;
    private OAuth2RestTemplate restTemplate;

    @Autowired
    public MBdevOrderApiDataService(@Value("endpoints.value.endpoint") String resource,
                                    @Qualifier("oAuth2RestTemplateMbDev") OAuth2RestTemplate restTemplate) {
        this.resource = URI.create(resource);
        this.restTemplate = restTemplate;
    }

    @Override
    public ListOrderItemApiDataDto getApiListData(String date, String productId, List<String> applicationStatus, String applicationId, String billingMetric, Boolean includeNonBillable) {

        ListOrderItemApiDataDto list = restTemplate.getForObject(resource, ListOrderItemApiDataDto.class);
        log.info("Data list");
        return null;
    }

}

所以我的问题是每次我尝试启动我的系统以测试它是否有效时,都会出现此错误消息(请在帖子末尾查看)

有人可以帮帮我吗?

编辑: 这是 orderController 中的调用方式->

private OrderService orderService;
private PoiOrderService poiOrderService;
private MBdevOrderApiDataService mBdevOrderApiDataService;

@Autowired
public OrderController(OrderService orderService, PoiOrderService poiOrderService, MBdevOrderApiDataService mBdevOrderApiDataService) {
    this.orderService = orderService;
    this.poiOrderService = poiOrderService;
    this.mBdevOrderApiDataService = mBdevOrderApiDataService;
}

@ApiOperation(value = "Get Data from API MbDev.")
@ApiImplicitParams({
        @ApiImplicitParam(name = "requestDate", dataType = "string", value = "The search date range from 'yyyy-MM'", defaultValue = "2021-12", paramType = "query")})
@ApiResponses(value = {
        @ApiResponse(code = HttpStatus.SC_OK, message = "The petition to get data API Mbdev proceed correctly"),
        @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "The petition to get data API Mbdev could not be processed.", response = ExceptionResponse.class),
        @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = "You don't have the necessary rights to use this endpoint. Please contact the admin."),
        @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "System error.", response = ExceptionResponse.class)
}) //</editor-fold>

@PostMapping(path = "/orders/api/mb-dev", consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<ListOrderItemApiDataDto> getExternalApiDataMbDev(@RequestParam(required = false) String requestDate) {
    List<String> applicationStatus = Arrays.asList(ApplicationStatus.BUSINESS.getValue(), ApplicationStatus.BUSINESS_TESTING.getValue());
    ListOrderItemApiDataDto dto = this.mBdevOrderApiDataService.getApiListData(requestDate,null, applicationStatus,null,null,true);
    return dto != null ? ResponseEntity.ok(dto) : ResponseEntity.notFound().build();

}

edit->完整日志:

2022-02-01 15:51:25.695 警告 25468 --- [主要] ConfigServletWebServerApplicationContext:遇到异常 在上下文初始化期间 - 取消刷新尝试: org.springframework.beans.factory.support.BeanDefinitionOverrideException: 中定义的名称为“oAuth2RestTemplate”的无效 bean 定义 类路径资源 [com/tss/pago/application/configuration/RestTemplateConfig.class]: 无法注册 bean 定义 [Root bean: class [null];范围=; 摘要=假;惰性初始化=空;自动线模式=3;依赖检查=0; 自动接线候选=真;主要=假; factoryBeanName=restTemplateConfig; factoryMethodName=oAuth2RestTemplate;初始化方法名=空; destroyMethodName=(推断);在类路径资源中定义 [com/tss/pago/application/configuration/RestTemplateConfig.class]] bean 'oAuth2RestTemplate': 已经有 [Root bean: class [null]; 范围=;摘要=假;惰性初始化=空;自动线模式=3; 依赖检查=0;自动接线候选=真;主要=假; factoryBeanName=nexnetRestTemplateConfig; factoryMethodName=oAuth2RestTemplate;初始化方法名=空; destroyMethodName=(推断);在类路径资源中定义 [com/tss/pago/application/configuration/NexnetRestTemplateConfig.class]] 边界。 2022-02-01 15:51:25.709 信息 25468 --- [主要] ConditionEvaluationReportLoggingListener:

***************************应用程序启动失败


说明:

在类路径资源中定义的 bean 'oAuth2RestTemplate' [com/tss/pago/application/configuration/RestTemplateConfig.class], 无法注册。具有该名称的 bean 已经 在类路径资源中定义 [com/tss/pago/application/configuration/NexnetRestTemplateConfig.class] 并且覆盖被禁用。

行动:

考虑重命名其中一个 bean 或通过设置启用覆盖 spring.main.allow-bean-definition-overriding=true

进程以退出代码 1 结束

【问题讨论】:

  • 尝试删除@ConditionalOnProperty,如果有帮助,请检查feature.toggles.value 是否设置正确。
  • 您能添加NexnetRestTemplateConfig 类吗?看来您正在尝试注册两次具有完全相同名称的 bean。
  • 我在阅读@talex 写的内容后进行了一些更改,首先我发现在控制器中,> private MBdevOrderApiDataService mBdevOrderApiDataService;我使用的是实现而不是服务。该服务没有注释 > @Service。最后 > @ConditionalOnProperty 有不正确的值。我全部更改它并显示一个不同的错误,因为即使 Bean 名称不同导致错误,OAuth2RestTemplate 也是相同的方法名称,在我更改项目后最终启动。感谢您的所有帮助
  • 要么添加解决方案作为答案并接受它,要么干脆删除问题。谢谢!

标签: java spring spring-mvc autowired


【解决方案1】:

您不需要在构造函数参数中传递 OAuth2RestTemplate 只需使用 @Autowired@Qualifier 如下所示,并在需要的地方使用 restTemplate。 Autowired 将自动注入 OAuth2RestTemplate 值,您不需要在构造函数上显式设置它。

@Autowired
@Qualifier("oAuth2RestTemplateMbDev")
private OAuth2RestTemplate restTemplate

所以你的代码看起来像这样

@Slf4j
@Service
@ConditionalOnProperty(name = "feature.toggles.value", havingValue = "true", matchIfMissing = true)
public class MBdevOrderApiDataService implements OrderItemApiData {

    private URI resource;
    @Autowired
    @Qualifier("oAuth2RestTemplateMbDev")
    private OAuth2RestTemplate restTemplate

   
    public MBdevOrderApiDataService(@Value("endpoints.value.endpoint") String resource) {
        this.resource = URI.create(resource);
        
    }

    @Override
    public ListOrderItemApiDataDto getApiListData(String date, String productId, List<String> applicationStatus, String applicationId, String billingMetric, Boolean includeNonBillable) {

        ListOrderItemApiDataDto list = restTemplate.getForObject(resource, ListOrderItemApiDataDto.class);
        log.info("Data list");
        return null;
    }

}

【讨论】:

  • 我已经试过了,结果是一样的。
  • 你能把整个错误日志贴出来
  • 添加在编辑帖的末尾
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2013-01-16
  • 2012-05-23
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
相关资源
最近更新 更多