简体   繁体   中英

Qualifier for Bean dont found name in @Service constructor

I am trying to call a method to set rest template values using OAuth2RestTemplate, I created a configure file in other part of the project (there is a core part of the project and an application part, no depency between them) that has a bean to OAuth2RestTemplate:

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;
}

This is the one I created it, the other already exist: @Bean(name = "oAuth2RestTemplateMbDev") public OAuth2RestTemplate oAuth2RestTemplate(MbdevOAuth2Properties resource, Proxy proxy)

So to be able to use 2 Bean for the same class I assign name to be call using @Qualifier.

Like this:

@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;
    }

}

so my problem is that each time i try to launch my system to test if this works this error message appears (check at the end of the post)

Can someone give me a hand?

edit: this is how is called in the 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-> full log:

2022-02-01 15:51:25.695  WARN 25468 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'oAuth2RestTemplate' defined in class path resource [com/tss/pago/application/configuration/RestTemplateConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=restTemplateConfig; factoryMethodName=oAuth2RestTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/tss/pago/application/configuration/RestTemplateConfig.class]] for bean 'oAuth2RestTemplate': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=nexnetRestTemplateConfig; factoryMethodName=oAuth2RestTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/tss/pago/application/configuration/NexnetRestTemplateConfig.class]] bound.

2022-02-01 15:51:25.709  INFO 25468 --- [           main] ConditionEvaluationReportLoggingListener : 

APPLICATION FAILED TO START


Description:

The bean 'oAuth2RestTemplate', defined in class path resource [com/tss/pago/application/configuration/RestTemplateConfig.class], could not be registered. A bean with that name has already been defined in class path resource [com/tss/pago/application/configuration/NexnetRestTemplateConfig.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

Process finished with exit code 1

you don't need to pass OAuth2RestTemplate in constructor parameter just use @Autowired and @Qualifier like below and use restTemplate wherever you required. Autowired will automatically inject OAuth2RestTemplate value you don't required to set it explicitly on constructor.

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

So your code look like this

@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;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM