Spring Framework: Page 2

DIPANSHU GOYAL
Sep 2, 2018 · 7 min read

This is in continuation of my previous page on Spring Framework. I would recommend you to clone this GIT Repository for this session. This repository contains

  1. Sample code that shows the usage of Spring concepts in applications.
  2. Test code to practice various features of Spring.

Spring: Configuration with Component Scan

We saw in the last session, how Spring Beans can be constrcuted using a combination of @Bean and @Configuration annotations . In my opinion, this is ok for a simple application which has got less number of Beans with few dependencies. However if a Spring application is massive with large number of Beans , where some Beans are complex and have dependency on other Beans, then the dependency list (which is marked with autowire annotation in below example)and the list of Beans to be created will be huge in a configuration file. It will make configuration file hard to maintain.

Example :

@Configuration
Class ApplicationConfiguration {
// Dependency list
@Autowire
EmployeeDao employeedao
@Autowire
DepartmentService departmentService
...
...
...
// List of beans to be created
@Bean
public EmployeeService employeeService() {
return new EmployeeService(departmentService, employeedao);
}
@Bean
.....
@Bean
....
....}

Ignore @Autowire now if you don’t understand as It’s a separate topic. Remember for now that this is one way of injecting dependencies.

Whatever I described above is a one way of instantiating and managing spring Beans.

Another way of constructing Beans is using @ComponentScan annotation with @Configuration.

If a Spring Application is configured with @ComponentScan annotation then Spring initialises the application by scanning packages, reads annotations on each class in the given package and creates Spring Beans (i.e. instantiate object and inject dependencies). Does it sound cool ? The difference is that Spring autoscans packages, creates beans and resolves dependencies by itself and no need to explicitly mention each bean in the configuration file.

I normally go by this process, why ?

> No need to create Beans in any configuration files .Imagine an application has 200 classes, do you want to create Beans of each one and maintain the dependency list ?

> I really like this because a class knows what are its dependencies, so let it resolve by itself i.e. Class can define it’s list of dependencies and we don’t need to maintain in any configuration class. Example, If EmployeeService depends on DepartmentService and EmployeeDao then the dependency list can be added in the class itself and let Spring resolves dependencies for the class.

@Service
Class EmployeeService {
// Dependency list
@Autowire
EmployeeDao employe
@Autowire
DepartmentService departmentService

Spring while creating Bean for “employeeService” , finds and construct Beans for all dependencies and injects in the class.

Now we know that @ComponentScan is another way of creating beans and we understand the importance of this way, Let’s dig more to find out how it can be used in Spring Application.

I have divided the document into three different sections —

  1. An application structure — Almost similar to what we have in our real project.
  2. What are the Spring annotations involved in creating beans.
  3. Implemention of Spring annotations in the application structure.

Application structure:-

I drew a normal application which consists of controllers, services, repositories and other components. Let’s say, a request comes and controller receives a request , forward it to service layer which uses components to create domain object or manipulate data and passes it to repository layer which persist into DB.

Request flow from

Each type of class is put into it’s own package like services are added into *.service package which is inline with our real applications where we tend to create separate packages for different sets of classes.

Application Structure: separate package for different types of Classes

Here, the application has a base package com.learnbypractice.app.simple and separate packages are created for each layer like -

> com.learnbypractice.service stores all services

> com.learnbypractice.component has got all components

> com.learnbypractice.repository for repositories

> and com.learnbypractice.controller for all controllers.

2. Spring Annotations:-

As part of the section we will learn about annotations required to scan packages, reads classes and construct Beans.

@Configuration — Classes annotated with @Configuration, represent a spring configuration files. Spring application uses configuration files to initialise Spring Container.

@ComponentScan — This annotation is used in conjunction with @Configuration. , and it tells spring what packages to scan and what types of classes to read and instantiate.

In figure below, Configuration + ComponentScan scans a base package.

Do you think now Spring can construct Beans based on classes available in the package — “com.learnbypractice.app.simple” ?

Answer is ‘No’. These two annotations tell spring which package to scan for classes but it’s not sufficient to construct Beans.

There are few other annotations which enable Spring-ComponentScanner to identify the classes for constructing beans.These are —

  1. @Service
  2. @Controller
  3. @Repository
  4. @Component.

These are called stereotype annotations snd specific purpose of individual annotation is different and that we see as we go deeper into the Spring session. However, what’s common in these annotations is they are read by the Spring to identify classes in order to construct Beans in spring container.

As we now familiar with different annotations required to create Spring beans, Let’s try to establish connection between ComponentScan and these stereotype annotations.

We know in brief that Configuration and ComponentScan annotations are used to scan packages ,read classes and construct Beans. However, not all the classes in the given package are qualified for Spring Beans. Only classes annotated with @Service , @Controller, @Repository, @Component are participated in the bean creation and others are simply ignored.

In the figure below, We have defined classes and some of them are marked with annotations and some are left out i.e pure java beans with `No annotation`. So classes marked with stereotype annotations are qualified for Spring Beans and other are ignored.

In short, ComponentScan, Configuration scans packages and looks for classes annotated with Service, Controller, Repository & Component to construct Beans.

Additional Detail:

ComponentScan annotation comes with a default option of scanning the given package and instantiating Beans from Services, Controllers, Repositories and Components available in the package. However there is an option to add filter in order to generate Beans from specific type of Class.

In the above figure, you can add Filter criteria to instantiate only Services or Controllers. For now, remember that this option is available and some later session we will understand why this option is important.

3. Implementation :-

We will see how to instantiate Spring Beans from the annotations covered in the last section. We will begin focussing on single layer and as we make progress we will understand how classes in multiple layers can be instantiated as Spring Beans.

Controllers > Here, we will see what annotations and their settings are required to instantiate all controllers available in basePackage com.learnbypractice.app.simple.

Below figure shows that we need a configuration file (i.e. a Class annotated with Configuration and ComponentScan annotations) which scans basePackage, finds all classes marked with controller annotation in the package and starts instantiating as Beans.

Now it’s time to practice what we have learnt.

Configuration Class — A class with annotations @Configuration, @ComponentScan. In order to check for Controller, we need to provide basePackage and filter for controller annotation.

InitializeControllerBeansWithConfigurationAndComponentScan

Test Class —

InitializeControllerBeansWithConfigurationAndComponentScanTest

Application Code uses the configuration file to construct Beans —

InitializeControllerBeansWithConfigurationAndComponentScanApplication

Services > Let’s try how in instantiate Services in any given package. Process is same as we need a configuration file which scans basePackage , reads classes and instantiating Beans. Only difference is we need to provide filter for services.

Configuration Class —

InitializeServiceBeansWithConfigurationAndComponentScan

Test Class —

InitializeServiceBeansWithConfigurationAndComponentScanTest

Application Code uses the configuration file to construct Beans —

InitializeServiceBeansWithConfigurationAndComponentScanApplication

Repository > Similarly, Spring Beans can be constructed using a configuration file scanning all classes annotated with Repository annotation.

Configuration Class —

InitializeRepositoryBeansWithConfigurationAndComponentScan

Test Class —

InitializeRepositoryBeansWithConfigurationAndComponentScanTest

Application Code uses the configuration file to construct Beans —

InitializeRepositoryBeansWithConfigurationAndComponentScanApplication

Component > This is a special kind of stereotype annotation because there are other some annotations which are annotated with component annotations so If componentScanner is configured to scan component annotation then classes marked with @Services, @Controller, @Controller, @Configurations are all instantiated as Spring Beans.

Configuration Class —

InitializeComponentBeansWithConfigurationAndComponentScan

Test Class —

InitializeComponentBeansWithConfigurationAndComponentScanTest

Application Code uses the configuration file to construct Beans —

InitializeComponentBeansWithConfigurationAndComponentScanApplication

Question — Can you try to answer ? If you have two configuration files and one is scanning Services and other is scanning Repositories..How many types of Spring Beans are created ?

Answer is available in next Part.

If you like this Part, please Clap, Share and provide your valuable feedback.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade