saran3h
saran3h

Reputation: 14022

Spring boot - multiple RestTemplate implementations based on Spring profile

I'm trying to load different RestTemplates for different profiles. One of the rest template config is available inside a jar that is used in the project. Here is how I implemented it:

RestTemplateProviderConfiguration.java

package com.my.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import static org.apache.commons.lang.StringUtils.equalsIgnoreCase;

@Configuration
public class RestTemplateProviderConfiguration {
    @Autowired
    private ApplicationContext appContext;

    @Value("${spring.profiles.active:}")
    private String activeProfile;

    @Value("${iam.rest.template:}")
    private String iamRestTemplateQualifier;

    @Bean
    public RestTemplate restTemplate() {
        return equalsIgnoreCase(activeProfile, "local") ? new RestTemplate() : (RestTemplate) appContext.getBean(iamRestTemplateQualifier);
    }
}

Service.java

...
@Autowired
private RestTemplateProviderConfiguration restTemplateProviderConfiguration;
...

public void testRestClient() {
    return restTemplateProviderConfiguration.restTemplate()
                    .exchange(...);
}

Can anyone suggest a better method where I can just use:

@Autowire
RestTemplate restTemplate;

and it will load the correct template based on the active spring profile?

Solution #1 (doesn't work): I've created two beans and have loaded them conditionally based on active profile. However, it does not load the template that's available in jar for non-local profile:

@Bean
@Profile("local")
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@Bean
@Profile("!local")
public RestTemplate iamrestTemplate() {
    return new RestTemplate();
}

Upvotes: 1

Views: 3265

Answers (2)

Ori Marko
Ori Marko

Reputation: 58774

You should have 2 different @Configuration, for each profile with equivalent profile as @Profile({"local"})

Each configuration will return different implementation of RestTemplate (and other relevant beans)

You can also define Profile per Bean, but it could be confusing

@Profile("profile")
@Bean
MyBean myBean(MyBeanProperties properties) {

Upvotes: 2

Pavel Slabikov
Pavel Slabikov

Reputation: 46

If you are using Spring 5.1.4+, you can specify @Profile annotation for your RestTemplate beans.

@Bean
@Profile("local")
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@Bean
@Profile("!local")
public RestTemplate iamrestTemplate() {
    return new RestTemplate();
}

See javadoc for this annotation.

Upvotes: 2

Related Questions