Search code examples
springspring-bootlambdafunctional-interface

Understanding the instance variable names and the methods to create it using Spring @Bean annotation


I have written a simple Spring Boot Application, which I would later extend to build a Spring REST client. I have a working code; I have tried to change a few instance variable names and method names and playing around.

Code:

@SpringBootApplication
public class RestClientApplication {

public static void main(String[] args) {
    SpringApplication.run(RestClientApplication.class, args);

    try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
            RestClientApplication.class)) {
        System.out.println(" Getting RestTemplateBuilder : " + ctx.getBean("restTemplateBuilder"));
        System.out.println(" Getting RestTemplate : " + ctx.getBean("restTemplate"));
    }
}

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.build();
}

@Bean
public CommandLineRunner runner() {
    return args -> { SOP("hello"); }
}

}

Observations:

  1. The instance variable names follow the camel-case notation, as expected. So, restTemplate and restTemplateBuilder works.
  2. While creating a RestTemplate instance through restTemplate() method, I tried changing the name of the argument to builder. It works.
  3. While creating a RestTemplate instance through restTemplate() method, I tried changing the name of the method to a random one and I get an exception that "No bean named 'restTemplate' available".
  4. CommandLineRunner interface is implemented through a lambda expression. Accessing commandLineRunner throws an exception.

Question

Why do I see the results mentioned in point #2 and #3?


Solution

  • While creating a RestTemplate instance through restTemplate() method, I tried changing the name of the argument to builder. It works.

    This works because, By default spring autowire's by type. So it searches for a bean with type RestTemplateBuilder and it finds it and hence no error.

    While creating a RestTemplate instance through restTemplate() method, I tried changing the name of the method to a random one and I get an exception that "No bean named 'restTemplate' available".

    You are getting an exception not because you changed the method name, but because of this

    ctx.getBean("restTemplate")
    

    Because by default @Bean uses method name as name of the bean. (check this). So the name of the bean of type RestTemplate which is returned by your random method is name of your random method. Hence when you try to get a bean with name restTemplate, it throws exception.

    But if you were to Autowire a bean of type RestTemplate, it would still work, because Spring will Autowire by type by default and it knows a bean of type RestTemplate(name as random method name).