简体   繁体   中英

Spring boot: @Profile @Bean combination doesn't work

I've coded these two beans:

@Bean
public HttpClient httpClient() throws Exception {
    LOG.debug("http client for NO PRE");

    return HttpClients.custom().build();
}

@Bean
@Profile("pre")
public HttpClient httpClientPre() throws Exception {
    LOG.debug("http client for PRE");

    //...

    HttpClient client = HttpClients.custom().build();

    return client;
}

By other side, I've this another bean:

@Bean
@Primary
public RestTemplate restTemplate(RestTemplateBuilder builder, HttpClient httpClient) throws Exception {
    return builder.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient))
            .build();
}

As you can figure out, when "pre" is active I want httpClientPre is reached. However, in spite of active profile is "pre", it's not reached. See logs:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.4.RELEASE)

13:20:31.746 [main] INFO  n.g.t.e.s.SchedulerApplication - Starting SchedulerApplication on psgd with PID 9538 (/home/jeusdi/projects/repositori-digital/rep-digital-scheduler/target/classes started by jeusdi in /home/jeusdi/projects/repositori-digital)
13:20:31.760 [main] DEBUG n.g.t.e.s.SchedulerApplication - Running with Spring Boot v2.0.4.RELEASE, Spring v5.0.8.RELEASE
13:20:31.767 [main] INFO  n.g.t.e.s.SchedulerApplication - The following profiles are active: pre  <<<<<<<<<<<<

However, I was expecting to get log for "http client for PRE" . Nevertheless, I'm getting:

13:20:48.613 [main] DEBUG n.g.t.e.s.c.ServicesConfiguration - http client for NO PRE <<<<<<

It means that httpClientPre is not reached in spite of current profile is pre .

Any ideas?

EDIT

I've also tried with @Profile("!pre") , but I'm getting this message:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of method restTemplate in net.gencat.transversal.espaidoc.scheduler.config.ServicesConfiguration required a bean named 'httpClient' that could not be found.


Action:

Consider defining a bean named 'httpClient' in your configuration.

EDIT2

I've also tried with:

在此处输入图像描述

But it keep getting message above.

It seems you should mark all @Bean methods with @Profile

According to https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html

NOTE: With @Profile on @Bean methods, a special scenario may apply: In the case of overloaded @Bean methods of the same Java method name (analogous to constructor overloading), an @Profile condition needs to be consistently declared on all overloaded methods. If the conditions are inconsistent, only the condition on the first declaration among the overloaded methods will matter. @Profile can therefore not be used to select an overloaded method with a particular argument signature over another; resolution between all factory methods for the same bean follows Spring's constructor resolution algorithm at creation time. Use distinct Java method names pointing to the same bean name if you'd like to define alternative beans with different profile conditions; see ProfileDatabaseConfig in @Configuration's javadoc.

The reason here is that you are creating beans with 2 different names (method name == name of bean) and name of bean is taken into account when injection happens - there bean name == argument name.

In your case you are injecting httpClient but you are creating httpClient and httpClientPre - thus httpClient is injected

using @Profile("!pre") is the way to go but in conjunction with @Qualifier so you can name the bean correctly, eg.

@Bean
@Profile("!pre")
public HttpClient httpClient() throws Exception 

@Bean
@Profile("pre")
@Qualifier("httpClient")
public HttpClient httpClientPre() throws Exception 

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