简体   繁体   中英

Autowire bean from @Configuration

I am new to Spring, I am getting the exception "No qualifying bean of type [int] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}". When i try the below approach.

This is the configuration for the RestTemplate

@Configuration
public class RestClientConfig {

@Bean
public ObjectMapper getObjMapper(){
return new ObjectMapper();
}

@Bean
public RestTemplate createRestTemplate(int maxTotalConn, int maxPerChannel, int connTimout) {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    connectionManager.setMaxTotal(maxTotalConn);
    connectionManager.setDefaultMaxPerRoute(maxPerChannel);

    RequestConfig config = RequestConfig.custom().setConnectTimeout(connTimout).build();
    CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
            .setDefaultRequestConfig(config).build();
    ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);

    RestTemplate restTemplate = new RestTemplate(factory);

    restTemplate.setErrorHandler(new RestResponseErrorHandler());
    restTemplate.setMessageConverters(createMessageConverters());

    return restTemplate;
}

private List<HttpMessageConverter<?>> createMessageConverters() {
    List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
    MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
    jsonMessageConverter.setObjectMapper( getObjMapper());
    messageConverters.add(jsonMessageConverter);
    return messageConverters;
}

}

When i try to access like this, it causing the exception mentioned above.

@Autowired
private RestClientConfig restTemplate;

ResponseEntity<String> response2 = restTemplate.createRestTemplate(100, 100, 100).exchange( url, HttpMethod.GET, entity , String.class );

Please can some one help and point me the correct approach and what i am doing anything wrong?

You need to inject the RestTemplate , not the config class

@Autowired
private RestTemplate restTemplate;

instead of:

@Autowired
private RestClientConfig restTemplate;

EDIT

Here is one way to pass your arguments to your class:

//EXAMPLE @Value("${propFile.maxTotalConn}")


@Bean
public RestTemplate createRestTemplate(@Value("${propFile.maxTotalConn}") int maxTotalConn, @Value("${propFile.maxPerChannel}") int maxPerChannel, connTimoutint connTimout) {
   PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
   connectionManager.setMaxTotal(maxTotalConn);
   connectionManager.setDefaultMaxPerRoute(maxPerChannel);

  ...
}

EXPLANATION

Create a properties file (*.properties) and place in your src/main/resources folder. Include your properties in it as the code above suggests. @Value is a Spring annotation that searches for the properties file on the classpath and injects the values while creating your Spring bean.

This is to do with the following line of code in your configuration

public RestTemplate createRestTemplate(int maxTotalConn, int maxPerChannel, int connTimout);

Spring expects the three integer parameters to be available when it creates the bean. Where are the values supposed to come from.

You can use make use of property files (Spring property abstraction) to inject the 3 fields

First option supply the parameters in your environment and inject the Environment instead

public RestTemplate createRestTemplate(Environment env){
    int maxTotalConn = env.getRequiredProperty("pool.maxSize" , Integer.class);
//lookup remaining parameters
}

Then make sure you have a property file eg http-connection-pool.properties containg the settings. Specify it on your configuration file

@Configuration
@PropertySource("classpath:http-connection-pool.properties")
public class RestClientConfig {

}

Then add the http-connection-pool.properties to the root of your classpath

You can also use the @Value annotation with property placheolders to achieve the same

@Bean
public RestTemplate createRestTemplate(@Value("${pool.maxSize}")int maxTotalConn, @Value("${pool.maxPerChannel}")int maxPerChannel, @Value("${pool.connectionTimeout}")int connTimout) {
//more code
}

However with this approach you need to register a PropertySourcesPlaceholderConfigurer as follows

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}

And you still need to add the property files on your configuration class

Configuration classes are used to tell spring which objects you want to use as beans. You have properly marked RestTemplate class as a @Bean, so you can easily autowire it into other classes through application.

@Autowired
private RestTemplate restTemplate;

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