The objective of this post is to get an understanding of what @SpringBootApplication annotation does in a Spring Boot application. Sometimes we just tend to add an annotation, everything works magically and we are happy.
But when we want to make a few changes, things start breaking, components are not found and then we blame the magic that we enjoyed earlier.So it is always a good idea to get a better understanding of what some of these annotations do.
In a Spring Boot application, we need a class with a main method annotated with @SpringBootApplication annotation as shown below:
package com.boot.jpa;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaApplication.class, args);
}
}
This is the starting point for a Spring Boot application. The @SpringBootApplication annotation is really a short hand annotation or a combination of the following annotations:
1. @SpringBootConfiguration
This signifies that the application is not just a normal Spring application but a Spring Boot application. Actually this is just a combination of @Configuration+ Spring Boot, so more of a specialization. @Configuration applied on a file signifies that the class contains spring bean configurations using @Bean.
2. @EnableAutoConfiguration
This is the super intelligent annotation which kicks in the auto configuration for Spring Boot. Auto configuration is done by inspecting the classpath and configuring necessary beans that may be required. If you were to provide your own configuration, then Spring Boot will not re-configure the bean again.
How is this auto configuration done ?
Auto Configuration is done via a SpringFactoriesLoader class which will pick up and read the META-INF/spring.factories file. It is like a hook into instantiating certain beans found on the classpath. A sample of the same is shown below. EnableAutoConfiguration class is the ‘key’ below and it can have many ‘values’ as classes. These are read and conditionally configured depending on what is already configured by the developer and what is found on the classpath. For example, only if RabbitMQ and Spring AMQP client are found on the classpath usually added via maven or gradle, then Spring Boot tries to configure RabbitMQ.
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
....
3. @ComponentScan
Any Spring application will usually consist of beans which will be managed by Spring framework. To tell Spring framework to manage a bean, we use @ComponentScan. This annotation will scan all your beans and register it with the Spring Application Context. Later, you could inject the beans using @Autowired. Examples of a Component are classes annotated with @Controller, @Repository, @Service etc.
One has to be careful as @ComponentScan will scan the packages below the package from where this is defined.
A better way to organize your packages would be to have the class containing the @SpringBootApplication in the root package of your application so that all sub packages get scanned and beans are registered with application context. If this is not possible for some reason, you can of course add @ComponentScan annotation and specify the base package(s) to scan for spring beans.
Conclusion
Annotations in the Spring or Spring Boot framework makes the life of a developer easy and increases productivity.However it is important to understand the ‘what and how’ of these annotations to be a more effective and efficient developer.