1. Overview
The Spring framework lets us configure the application context in different ways which include XML-based, Java-based and annotation-based approaches.
In this tutorial, we're going to look at Spring's annotation-based configuration. In the end, we'll have a sample application configured through the usage of Spring annotations.
2. @Component Annotation
Firstly, let's look at how we can define a bean.
For this purpose, Spring provides the @Component annotation which marks a class as a bean. Although there are other stereotype annotations like @Service and @Controller, the @Component annotation is the most fundamental one. During the application startup, Spring parses the @Component annotated classes and creates bean definitions:
@Component
public class ChatRoomService {
public void start(){
System.out.println("Starting chat room");
}
}
Here, we have ChatRoomService class and we're annotating it with @Component. After the application startup, an instance of ChatRoomService will live as a bean in the ApplicationContext.
The @Component annotation also lets us define a bean name:
@Component("history")
public class HistoryService {
public void store(){
System.out.println("Storing the history");
}
}
Here, we're annotating the HistoryService class with @Component. Moreover, we're defining the bean's name as history.
3. @Autowired Annotation
Now, let's look at how we can wire beans.
In the previous examples, we've just created beans living in isolation. In order to compose a bean with another bean, Spring provides the @Autowired annotation. The main purpose of this annotation is to wire a bean into another bean as a dependency:
@Component
public class ChatService {
private final HistoryService historyService;
private final ChatRoomService chatRoomService;
@Autowired
public ChatService(HistoryService historyService, ChatRoomService chatRoomService) {
this.historyService = historyService;
this.chatRoomService = chatRoomService;
}
// Other methods
}
Here, we're creating another bean - ChatService. Additionally, we're specifying previously created beans as instance members of ChatService. In order for Spring to inject these beans, we're annotating the constructor with @Autowired. As a result, Spring will look for HistoryService and ChatRoomService beans in the application context and then will pass them to the constructor.
4. @ComponentScan Annotation
Finally, let's look at how we can control component scanning.
Spring should scan our application to find the @Component annotated classes. Moreover, it should also search for @Autowired usages to auto-wire beans. For this purpose, Spring gives us the @ComponentScan annotation. Through the usage of @ComponentScan, we can tell Spring under which packages it should look for components. Although specifying package names is the most common approach, the @Component annotation provides other means to fine-tune the scanning process:
@ComponentScan
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
ChatService chatService = applicationContext.getBean(ChatService.class);
chatService.chat();
applicationContext.close();
}
}
Here, we have the Application class which is annotated with the @ComponentScan annotation. Note that in our case @ComponentScan doesn't have any package specification. This is because when the package name is not specified, Spring starts looking for components from the current package. As an example, @ComponentScan("com.javabyexamples.spring.core.annotationconfig") produces the same result.
5. Overview
In this tutorial, we've looked at annotation-base configuration of Spring. We've also seen the usages of @Component, @Autowired and @ComponentScan annotations.
Check out the source code over on Github.