Annotations in Spring and Spring Boot Frameworks(1)
Nowadays everyone uses Spring and Spring Boot Framework to develop their Web Applications. There are tons of annotations used in the Spring framework. However, most developers don’t know the usage and functionality of those annotations. It is not a good practice. To help you understand the frequently used annotations in Spring Boot and their usage of those I have written this article.
Since you started with Spring Boot Application you know that Spring Boot Application has the main method. That main method has a main spring boot annotation called @SpringBootApplication.
@SpringBootApplication
This @SpringBootApplication annotation is a combination of 3 main annotations called,
- @EnableAutoConfiguration
- @ SpringBootConfiguration
- @ ComponentScan
This annotation does a lot of things when running Spring Application. This is an application entry point and should be annotated in the starter class or spring boot main entry point.
@SpringBootConfiguration
This annotation internally uses @Configuration annotation. This configuration is used for Java-based configurations where we can define the bean definitions inside this class so Spring IOC can load it. By using the @SpringBootConfiguration annotation, your class is transformed into a configuration source for your Spring Boot application. This annotation is used internally to achieve this purpose. Configuration classes come in handy when you need to customize the creation of objects within your application by combining the bean method with the configuration intuition. You can create custom beans and configurations for various purposes. This is often used to configure components like Rest Template and JDBC Template, as well as to print boot-specific configurations such as Kafka and Spring Batch.
There are 3 types of configuration we can do in a Spring-based application.
- XML-based configuration
- Annotation based configuration
- Java-based configuration
Java-based configuration in Spring provides a concise, expressive, and flexible approach to configuring Spring applications using plain Java code. To do a java based configuration we need to use @Configuration annotation. We can create a Java class and annotate that class as @Configuration and become a Spring Java-based configuration class. Then we can configure beans inside this class.
@EnableAutoConfiguration
The @EnableAutoConfiguration annotation is all about automating the configuration of your Spring Boot application. It works by automatically configuring beans that are present in the classpath, making it much easier for developers to set up and run their applications without needing to manually configure every single bean.
For example, if you have the Tomcat-embedded.jar in your classpath, Spring Boot will automatically create a TomcatEmbeddedServletContainerFactory bean to configure the Tomcat server for you. This eliminates the need for developers to write extensive configuration code, reducing boilerplate and simplifying the development process.
One way to explore the auto-configuration classes that Spring Boot uses is to check the spring-boot-autoconfigure.jar. Inside this JAR, you can find a file called /META-INF/spring-autoconfigure-metadata.properties, which lists the auto-configuration classes. This provides a handy reference for the automatic bean configuration happening under the hood.
@ComponentScan
The @ComponentScan annotation is a built-in functionality in Spring Boot applications. It plays a crucial role in identifying Spring beans available within your application. Essentially, it scans the base package and all its sub-packages to find these beans.
In the entry point class, you can see our main annotation @SpringBootApplication and it internally contains @ComponentScan annotation.
And it will automatically scan all the components inside the base packages and all the sub-packages.
Example:
Inside the pack1, I will create a Spring class called SpringComponent. This class has a method called ‘get message()’. Currently, it is not a Spring component. To make it one, we need to add a Spring-provided stereotype annotation, such as the ‘component’ annotation. Once we add this annotation, the class will be scanned during application startup and registered in the Spring application context or IOC container. This will allow it to function as a Spring component.
package com.spring.unittest.pack1;
import org.springframework.stereotype.Component;
@Component
public class SpringComponent {
public String getMessage() {
return "Initialize SpringComponent Class";
}
}
The entry point class has a main method and a run method that returns the application context, which is a Spring IOC container containing all the Spring components. To obtain the application context, call the run method with a ConfigurableApplicationContext object and assign the result to a variable called “applicationContext”. Then, retrieve the Spring bean by calling the getBean method on the applicationContext object and assign it to a variable named “springComponent”. Now we get the SpringComponent from the applicationContext(Spring IOC Container which contains all the Spring beans). And now you have the SpringComponent component and we can print the message.
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(UnittestApplication.class, args);
SpringComponent component = applicationContext.getBean(SpringComponent.class);
System.out.println(component.getMessage());
}
Now let's check whether this component is configured properly or not. Run Spring Application and you will get an output like this.
It says that @ComponentScan annotation successfully scanned the sub-package pack1. Now you can see @ComponentScan annotation scan the base packages and all the sub-packages for Spring components.
In summary, the @SpringBootApplication annotation is a powerful entry point to Spring Boot, leveraging the capabilities of @EnableAutoConfiguration, @ComponentScan, and @SpringBootConfiguration to streamline the development process. With this annotation, Spring Boot takes care of auto-configuring your application, scanning for Spring beans, and providing a foundation for custom configurations, allowing developers to focus on writing application logic rather than extensive setup and boilerplate code. This simplicity and automation are what makes Spring Boot an excellent choice for developing modern, efficient, and robust applications.
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans.
@Configuration and @Bean usage
These 2 annotations are used for Java-based annotations. If we use @Configuration it indicates that the class can be used by Spring IoC Container as a source of a bean definition.
Example:
When I annotate the BeanClass using @Configuration, Spring will expect this class to define a couple of Bean annotations. I defined a couple of Beans that will return the Object.
I created a bean called ExampleBean. To define this ExampleBean as a Spring Bean we can use @Component annotation. But I don’t want to do that, I want to define this bean inside my BeanClass. For that simply create an Object of it. And I can use the @Bean annotation for that Then immediately Spring IOC will search the @Configuration annotation and then inside it will search for the @Bean annotation. Then Spring IOC will create an Object of it and maintain the life cycle by itself.
BeanClass(Here you can create all the bean objects):
import com.example.demo.ExampleBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanClass {
@Bean
public ExampleBean exampleBean(){
return new ExampleBean();
}
}
Example Bean class:
package com.example.demo;
public class ExampleBean {
public void method(){
System.out.println("ExampleBean Method called ");
}
}
Controller class :
@GetMapping("/example")
public String example() {
exampleBean.method();
return "After calling exampleBean method";
}
Let me inject this bean somewhere so that I can access it. I can inject using @Autowired. In the controller, I can access the bean class using the example method.
When I access this URL “http://localhost:8080/api/example” it should call the method of bean class and print the message.
We didn't create the object of the test bean. It was just created by Spring IOC by reading this config class.
Difference between the @Configuration vs @SpringBootConfiguration
- @SpringBootApplication is a specialisation of @SpringBootConfiguration, which is a specialisation of @Configuration.
- You may only have one @SpringBootConfiguration, which means you can’t have both a @SpringBootConfiguration and a @SpringBootApplication in your application.
- @SpringBootConfiguration allows the configuration to be found automatically” which means you don’t have to do anything to have this (and therefore @SpringBootApplication) found. Other @Configuration classes are generally discovered by @ComponentScan
- An extra advantage over @Configuration is that it will be discovered by @StringBootTest.
In this article, we learned a couple of annotations like @SpringBootApplication, @SpringBootConfiguration, @Configuration, @EnableAutoConfiguration, and @ComponentScan in Spring and Spring Boot Frameworks. In the next article, we will learn about Stereotype Annotations.
Thank you!