0

I have an application consuming REST, and I want to parameterize my API token into the RestTemplate. I tried to autowire the bean containing the token, but the bean is still null at the time the RestTemplate is created. I think I can do this using @PostConstruct somehow, but I can't come up with the code. So I have this:

package com.company;
...
import com.company.api.dashboard.config.Credentials;

@SpringBootApplication
public class Main implements CommandLineRunner {
    @Autowired
    DashboardClient client;

    @Autowired
    Credentials credentials;

    public static void main(String... args) throws Exception {
        SpringApplication.run(Main.class, args);
    }

    @Bean
    public RestTemplate restTemplateAS(RestTemplateBuilder builder) {
         // here is where I try to use the autowired Credentials class
        return builder.additionalInterceptors(new ASRequestHeaderInterceptor("Authorization", "Bearer " + credentials.getApiToken()), 
                                              new ASRequestHeaderInterceptor("ContentType", MediaType.APPLICATION_JSON.toString()),
                                              new LoggingRequestInterceptor())
                .messageConverters(new MappingJackson2HttpMessageConverter())
                .requestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
                .build();
    }
    ...
}

And here is the Credentials bean:

package com.company.api.dashboard.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("credentials")
public class Credentials {
    private String oauthUser;

    private String oauthPassword;

    private String apiToken;

    public String getOauthUser() {
        return oauthUser;
    }

    public void setOauthUser(String oauthUser) {
        this.oauthUser = oauthUser;
    }

    public String getOauthPassword() {
        return oauthPassword;
    }

    public void setOauthPassword(String oauthPassword) {
        this.oauthPassword = oauthPassword;
    }

    public String getApiToken() {
        return apiToken;
    }

    public void setApiToken(String apiToken) {
        this.apiToken = apiToken;
    }
}

If I can't autowire that apiToken property, how else can I get it from my application.yml?

CNDyson
  • 1,687
  • 7
  • 28
  • 63
  • Bean "credentials" shouldn't be null since spring has to resolve it, please, check your spring config. – statut Mar 19 '18 at 13:26
  • It is null. I'm using annotations, and I believe them to be correct. – CNDyson Mar 19 '18 at 13:27
  • Which is the bean that is `null`? Where do you define that bean? – Sergii Bishyr Mar 19 '18 at 13:27
  • The `Credentials` bean is null. I define it as shown in my sample. – CNDyson Mar 19 '18 at 13:28
  • @user1660256 can you show how your bean looks like? What annotations do you have on top of your bean? How are you trying to inject the `apiToken`? – Sergii Bishyr Mar 19 '18 at 13:31
  • Edited to show `Credentials` – CNDyson Mar 19 '18 at 13:34
  • Okay, take a look at [this](https://stackoverflow.com/questions/7868335/spring-make-sure-a-particular-bean-gets-initialized-first) – Montassar El Béhi Mar 19 '18 at 13:39
  • Are you getting a NullPointerException? Post a stack trace also. Everything you have looks good. – Strelok Mar 19 '18 at 13:53
  • Is it the `Credentials ` bean `null` or the `apiToken`? I've tried to reproduce it, but my config class has been initialized properly. – Sergii Bishyr Mar 19 '18 at 13:55
  • Here is the message of the exception: `Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.client.RestTemplate]: Circular reference involving containing bean 'main' - consider declaring the factory method as static for independence from its containing instance. Factory method 'restTemplateAS' threw exception; nested exception is java.lang.NullPointerException` – CNDyson Mar 19 '18 at 13:55
  • The credentials bean is null. – CNDyson Mar 19 '18 at 13:58
  • It's shouldn't make much difference. But you can try to inject `Credentials` to the method instead of using `@Autowired`. It's just a wild guess, I will be surprised if this will help – Sergii Bishyr Mar 19 '18 at 14:05

1 Answers1

0

Annotate your main class with @EnableConfigurationProperties(Credentials.class) for the properties to be processed. And remove @Configuration from the Credetials class.

Strelok
  • 50,229
  • 9
  • 102
  • 115