Unit I
Unit I
Unit I
UNIT I: Spring 5 Basics : Why Spring, What is Spring Framework, Spring Framework - Modules,
Configuring IoC container using Java-based configuration, Introduction To Dependency
Injection, Constructor Injection, Setter Injection, What is AutoScanning
Pre Contents
Java Programming Fundamentals
Java Language Features
Spring is a popular open-source Java application development framework created by Rod Johnson.
Spring supports developing any kind of Java application such as standalone applications, web
applications, database-driven applications, and many more.
The basic objective of the framework was to reduce the complexity involved in the development of
enterprise applications. But today Spring is not limited to enterprise application development, many
projects are available under the Spring umbrella to develop different kinds of applications of today’s need
such as cloud-based applications, mobile applications, batch applications, etc. Spring framework helps in
developing a loosely coupled application that is simple, easily testable, reusable, and maintainable.
Spring is a Java-based framework for constructing web and enterprise applications. However, configuring
a Spring application is a tedious job. Even though it provides flexibility in bean configuration with multiple
ways such as XML, annotation, and Java-based configurations, there is no escape from the configuration.
Configuring the Spring features may need more time for developers and may distract the developers from
solving business problems.
Thanks to Spring Team for releasing Spring Boot, one of the topmost innovations in all the existing Spring
Framework. Spring Boot provides a new prototype for developing Spring applications with nominal effort.
Using Spring Boot, you will be able to develop Spring applications with extra agility and capacity to focus
on solving business needs with nominal (or possibly no) configuring.
In this course, we will discuss the core concepts of Spring Framework using Spring Boot that makes it
easy to create a production-grade, stand-alone application that we can just run.
In this course, we will look at a telecom application called InfyTel. InfyTel application is a Rest based
Application that provides functionality for adding, updating, and deleting a customer.
As the course proceeds, we will build this application incrementally to make it for learning the Spring core
concepts with Spring Boot.
Presentation Layer
Service/Business Layer
Persistence Layer
The service layer of an enterprise application is the layer in which the business logic is implemented. It
interacts with the persistence layer and the presentation layer.
In this course Spring Core with Boot, we will see how to develop the Service/Business layer for this
application. Once you have completed this course you can then learn to build the Persistence layer using
Spring JDBC with Spring Boot course and, to build the Rest presentation layer using Spring REST
course.
In this course, we will develop the service layer of this application and we will hardcode the persistence
layer.
Why Spring ?
Consider our InfyTel application here, we have a CustomerServiceImpl class which implements the
CustomerService interface.
1. package com.infy.service;
2.
3. public interface CustomerService {
4.
5. public String fetchCustomer();
6.
7. public String createCustomer(CustomerDto dto)
8.
9. }
The business logic of InfyTel application is implemented in this class. This class is used to perform
operations like creating a customer, deleting a customer, etc... CustomerServiceImpl class interacts with
CustomerRepository to perform the database related operations.
CustomerServiceImpl.java
13. }
If you want to unit test for createCustomer() method then you need a mock object of
CustomerRepository. But you cannot use a mock object because there is no way to substitute the
CustomerRepositoryImpl object that CustomerServiceImpl has. So testing CustomerServiceImpl
becomes difficult.
Also, you cannot use a different implementation of CustomerRepository other than
CustomerRepositoryImpl because of tight coupling.
So we need a more flexible solution where dependencies can be provided externally rather than a
dependent creating its own dependencies. Now let us see such an implementation
of CustomerServiceImpl class.
15.
This solution is more flexible and easy to test. But at the same time, it is tedious to manually wire together
with the dependencies. Also if you alter the dependencies you may have to change vast amounts of code.
So what is the solution?
We can use a technique called Dependency Injection (DI). It is a technique in which the responsibility of
creating and wiring the dependencies of a dependent class is externalized to the external framework or
library called dependency injection (DI) frameworks. So now the control over the construction and wiring
of an object graph is no longer resides with the dependent classes themselves. This reversal of
responsibilities is known as Inversion of Control(IoC). Dependency injection framework also called IoC
containers.
There are many third-party frameworks that are available for dependency injection such as Spring
Framework, Google Guice, Play Framework, etc. In this course, you will study about Spring Framework.
Besides dependency injection, there are many other advantages of using the Spring Framework which
you will study later in this course.
Note: Inversion of Control (IoC) represents the inversion of application responsibility of the object's
creation, initialization, dependency, and destruction from the application to the third party.
Spring Framework is an open source Java application development framework that supports developing
all types of Java applications such as enterprise applications, web applications, cloud based applications,
and many more.
Java applications developed using Spring are simple, easily testable, reusable, and maintainable.
Spring modules do not have tight coupling on each other, the developer can pick and choose the modules
as per the need for building an enterprise application.
Core Container: These are core modules that provide key features of the Spring framework.
Data Access/Integration: These modules support JDBC and ORM data access approaches in
Spring applications.
Web: These modules provide support to implement web applications.
Others: Spring also provides few other modules such as the Test for testing Spring applications.
Core Container of Spring framework provides the Spring IoC container and Dependency Injection
features.
Core: This is the key module of Spring Framework which provides fundamental support on which
all other modules of the framework are dependent.
Bean: This module provides a basic Spring container called BeanFactory.
Context: This module provides one more Spring container called ApplicationContext which
inherits the basic features of the BeanFactory container and also provides additional features to
support enterprise application development.
Spring Expression Language (SpEL): This module is used for querying/manipulating object
values.
AOP (Aspect Oriented Programming) and aspects: These modules help in isolating cross-cutting
functionality from business logic.
We will discuss BeanFactory and ApplicationContext containers in detail later in this course.
The Data Access/Integration module of Spring provides different data access approaches.
Java Database Connectivity (JDBC): It provides an abstract layer to support JDBC calls to
relational databases.
Object Relational Mapping (ORM): It provides integration support for popular ORM(Object-
Relational Mapping) solutions such as Hibernate, JPA, etc.
Transactions: It provides a simple transaction API which abstracts the complexity of underlying
repository specific transaction API's from the application.
Spring Framework Web module provides basic support for web application development. The Web
module has a web application context that is built on the application context of the core container. Web
module provides complete Model-View-Controller(MVC) implementation to develop a presentation tier of
the application and also supports a simpler way to implement RESTful web services.
Spring Framework provides the following modules to support web application development:
Web: This module has a container called web application context which inherits basic features
from ApplicationContext container and adds features to develop web based applications.
Webmvc: It provides the implementation of the MVC(model-view-controller) pattern to implement
the serverside presentation layer and also supports features to implement RESTful Web
Services.
WebFlux: Spring 5.0 introduced a reactive stack with a web framework called Spring WebFlux to
support Reactive programming in Spring's web layer and runs on containers such as Netty,
Undertow, and Servlet 3.1+.
WebSocket: It is used for 2 way communication between client and server in WebSocket based
web applications.
Spring Framework has few additional modules, test module is one of the most commonly used ones for
testing Spring applications.
Test: This module provides the required support to test Spring applications using TestNG or
JUnit.
Overall this is the big picture of Spring Framework. In this course, we will be discussing the highlighted
modules in detail.
The current version of Spring Framework is 5.x, the framework has been enhanced with new features
keeping core concepts the same as Spring 4.x.
There are few more changes in Spring 5.x with respect to library support and discontinued support, you
can refer to the Spring documentation for additional details.
Spring IoC
As discussed earlier, usually it is the developer's responsibility to create the dependent application object
using the new operator in an application. Hence any change in the application dependency requires code
change and this results in more complexity as the application grows bigger.
Inversion of Control (IoC) helps in creating a more loosely coupled application. IoC represents the
inversion of the responsibility of the application object's creation, initialization, and destruction from the
application to the third party such as the framework. Now the third party takes care of application object
management and dependencies thereby making an application easy to maintain, test, and reuse.
There are many approaches to implement IoC, Spring Framework provides IoC implementation
using Dependency Injection(DI).
Let us now learn more about Spring IoC through Dependency Injection.
We need not create objects in dependency injection instead describe how objects should be created
through configuration.
DI is a software design pattern that provides better software design to facilitate loose coupling, reuse, and
ease of testing.
Helps to create loosely coupled application architecture facilitating re-usability and easy testing.
Separation of responsibility by keeping code and configuration separately. Hence dependencies
can be easily modified using configuration without changing the code.
Allows to replace actual objects with mock objects for testing, this improves testability by writing
simple JUnit tests that use mock objects.
The core container module of the Spring Framework provides IoC using Dependency Injection.
The Spring container knows which objects to create and when to create through the additional details that
we provide in our application called Configuration Metadata.
Let us understand IoC containers and configuration metadata in detail on the go.
BeanFactory:
It is the basic Spring container with features to instantiate, configure and manage the beans.
org.springframework.beans.factory.BeanFactory is the main interface representing a BeanFactory
container.
ApplicationContext:
ApplicationContext is the preferred container for Spring application development. Let us look at
more details on the ApplicationContext container.
Let us now understand the differences between BeanFactory and ApplicationContext containers.
BeanFactory ApplicationContext
It does not support annotation based Support annotation based Dependency
Dependency Injection. Injection.
Support enterprise services such as
It does not support enterprise services.
validations, internationalization, etc.
By default, it supports Eager Loading.
By default, it supports Lazy Loading.
Beans are instantiated during load time.
// Loading ApplicationContext and
//Loading BeanFactory
instantiating bean
BeanFactory factory = new
ApplicationContext context = new
AnnotationConfigApplicationContext(Spring
AnnotationConfigApplicationContext(Sprin
Configuration.class);
gConfiguration.class);
// Instantiating bean during first access
// Instantiating bean during first access
using getBean()
using getBean()
CustomerServiceImpl service =
CustomerServiceImpl service =
(CustomerServiceImpl)
(CustomerServiceImpl)
factory.getBean("customerService");
context.getBean("customerService");
AbstractApplicationContext
You can see a warning message as Resource leak: 'context' is never closed while using the
ApplicationContext type. This is for the reason that you don’t have a close method with BeanFactory or
even ApplicationContext. AbstractApplicationContext is an abstract implementation of the
ApplicationContext interface and it implements Closeable and AutoCloseable interfaces. To close the
application context and destroy all beans in its abstractApplicationContext has a close method that closes
this application context.
1. The traditional way of accessing bean based on bean id with explicit typecast
context.getBean("customerService");
2. Accessing bean based on class type to avoid typecast if there is a unique bean of type in the container
1. CustomerServiceImpl service =
context.getBean(CustomerServiceImpl.class);
2.
3. Accessing bean through bean id and also type to avoid explicit typecast
The Spring configuration metadata consists of definitions of the beans that the container must manage.
XML Configuration
Annotation Based configuration
Java Based configuration
The Java-based configuration metadata is provided in the Java class using the following
annotations:
@Configuration: The Java configuration class is marked with this annotation. This annotation
identifies this as a configuration class, and it’s expected to contain details on beans that are to be
created in the Spring application context.
@Bean: This annotation is used to declare a bean. The methods of configuration class that
creates an instance of the desired bean are annotated with this annotation. These methods are
called by the Spring containers during bootstrap and the values returned by these methods are
treated as Spring beans. By default, only one bean instance is created for a bean definition by the
Spring Container, and that instance is used by the container for the whole application lifetime.
For example, the SpringConfiguration class can be configured in a Java class using the above
annotations as follows :
1. @Configuration
2.
3. public class SpringConfiguration {
4.
5. @Bean
6. public CustomerServiceImpl customerService() {
7.
8. return new CustomerServiceImpl();
9. }
10. }
11.
By default, the bean name is the same as the name of the method in which the bean is
configured. So in the above code bean name is customerService. If you want to change the bean
name then you can either rename the method or provide a different name with the name attribute
as follows:
1. @Configuration
2. public class SpringConfiguration {
3.
4. @Bean(name="service")
5. public CustomerServiceImpl customerService() {
6.
7. return new CustomerServiceImpl();
8. }
9. }
Highlights:
Demo Steps:
Let us understand the steps required to create a Maven project for Spring basic application using Spring
Tool Suite(STS)/Eclipse IDE.
Note: Screenshots of this demo have been taken from Eclipse IDE, however, the steps remain similar
even for the Spring Tool Suite IDE.
Goto File > new > Maven Project, you would get the below screen
Step 2: Let the current workspace be chosen as the default location for the Maven project. Click on next.
Step 4: Provide groupId as com.infy, artifactId as demo1, and retain the default version which is 0.0.1-
SNAPSHOT.
We can customize the package names as per our needs. In this demo, the package name is provided as
com.infy. Click on the finish button to complete the project creation.
Step 5: New project along with a POM.xml file is created as shown below
1. <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
3. <modelVersion>4.0.0</modelVersion>
4. <groupId>com.infosys</groupId>
5. <artifactId>demo1-spring-ioc</artifactId>
6. <version>0.0.1-SNAPSHOT</version>
7. <packaging>jar</packaging>
8. <name>demo1-spring-ioc</name>
9. <url>http://maven.apache.org</url>
10. <properties>
11. <spring.version>5.0.5.RELEASE</spring.version>
12. <project.build.sourceEncoding>UTF-
8</project.build.sourceEncoding>
13. </properties>
14. <dependencies>
15. <!-- Spring Dependency -->
16. <dependency>
17. <groupId>org.springframework</groupId>
18. <artifactId>spring-context</artifactId>
19. <version>${spring.version}</version>
20. </dependency>
21. <dependency>
22. <groupId>junit</groupId>
23. <artifactId>junit</artifactId>
24. <version>3.8.1</version>
25. <scope>test</scope>
26. </dependency>
27. </dependencies>
28. </project>
29.
Step 7: If the dependencies are not getting downloaded automatically update the Maven project as
shown below
Highlights:
CustomerService.java
1. package com.infy.service;
2.
3. public interface CustomerService {
4. public String createCustomer();
5. }
6.
CustomerServiceImpl.java
1. package com.infy.service;
2.
3. public class CustomerServiceImpl implements CustomerService {
4.
5. public String createCustomer() {
6. return "Customer is successfully created";
7. }
8.
9. }
10.
SpringConfiguration.java
1. package com.infy.util;
2.
3. import org.springframework.context.annotation.Bean;
4. import org.springframework.context.annotation.Configuration;
5. import com.infy.service.CustomerServiceImpl;
6.
7. @Configuration
8.
9. public class SpringConfiguration {
10.
11. @Bean(name = "customerService")
12. public CustomerServiceImpl customerServiceImpl() {
13. return new CustomerServiceImpl();
14. }
15. }
16.
Client.java
1. package com.infy;
2.
3. import
org.springframework.context.annotation.AnnotationConfigApplicationConte
xt;
4. import org.springframework.context.support.AbstractApplicationContext;
5. import com.infy.service.CustomerServiceImpl;
6. import com.infy.util.SpringConfiguration;
7.
8. public class Client {
9. public static void main(String[] args) {
10. CustomerServiceImpl service = null;
11. AbstractApplicationContext context = new
AnnotationConfigApplicationContext(SpringConfiguration.class);
12. service = (CustomerServiceImpl)
context.getBean("customerService");
13. System.out.println(service.createCustomer());
14. context.close();
15. }
16. }
Output:
For the previously discussed InfyTel Customer application, we defined CustomerService bean as shown
below
1. @Bean
2. public CustomerService customerService() {
3.
4. return new CustomerService();
5. }
This is the same as the below Java code wherein an instance is created and initialized with default values
using the default constructor.
Inversion of Control pattern is achieved through Dependency Injection (DI) in Spring. In Dependency
Injection, the developer need not create the objects but specify how they should be created through
configuration.
Spring container uses one of these two ways to initialize the properties:
Constructor Injection
Let us consider the CustomerService class of InfyTel Customer application to understand constructor
injection.
CustomerService class has a count property, let us now modify this class to initialize count property
during bean instantiation using the constructor injection approach.
1. package com.infy.service;
2.
3. public class CustomerServiceImpl implements CustomerService {
4. private int count;
5.
6. public CustomerServiceImpl(int count) {
7. this.count = count;
8. }
9.
10. }
1. @Configuration
2. public class SpringConfiguration {
3. @Bean // CustomerService bean definition with bean dependencies
through constructor injection
4. public CustomerServiceImpl customerService() {
5. return new CustomerServiceImpl(20);
6. }
A parameterized constructor is required in the CustomerService class as we are injecting the values
through the constructor argument.
So far, we learned how to inject primitive values using constructor injection in Spring. Now we will look
into inject object dependencies using Constructor injection.
1. package com.infy.service;
2. public class CustomerServiceImpl implements CustomerService {
3. // CustomerServiceImpl needs to contact CustomerRepository, hence
injecting the customerRepository dependency
4.
5. private CustomerRepository customerRepository;
6. private int count;
7. public CustomerServiceImpl() {
8. }
9.
10. public CustomerServiceImpl(CustomerRepository
customerRepository, int count) {
11. this.customerRepository = customerRepository;
12. this.count=count;
13. }
14. public String fetchCustomer() {
15. return customerRepository.fetchCustomer(count);
16. }
17.
18. public String createCustomer() {
19. return customerRepository.createCustomer();
20. }
21.
22. }
Observe in the above code, CustomerRepository property of CustomerSevice class has not been
initialized with any value in the code. This is because Spring dependency is going to be taken care of in
the configuration.
1. package com.infy.util;
2.
3. @Configuration
4. public class SpringConfiguration {
5.
6. @Bean// customerRepository bean definition
7. public CustomerRepository customerRepository() {
8. return new CustomerRepository();
9. }
10.
17.
Highlights:
Demo Steps:
SpringConfiguration .java
1. package com.infy.util;
2.
3. import org.springframework.context.annotation.Bean;
4. import org.springframework.context.annotation.Configuration;
5. import com.infy.repository.CustomerRepository;
6. import com.infy.service.CustomerServiceImpl;
7.
8. @Configuration
9.
10. public class SpringConfiguration {
11.
12. @Bean // Constructor Injection
13. public CustomerServiceImpl customerService() {
14.
15. return new CustomerServiceImpl(customerRepository(),
20);
16. }
17.
18. @Bean // Constructor Injection
19. public CustomerRepository customerRepository() {
20.
21. return new CustomerRepository();
22. }
23. }
24.
CustomerService.java
1. package com.infy.service;
2.
3. public interface CustomerService {
4. public String fetchCustomer();
5. public String createCustomer();
6. }
7.
CustomerServiceImpl.java
1. package com.infy.service;
2.
3. import com.infy.repository.CustomerRepository;
4.
5. public class CustomerServiceImpl implements CustomerService {
6.
7. private int count;
8. private CustomerRepository repository;
9.
10. public CustomerServiceImpl(CustomerRepository repository, int
count) {
11. this.count = count;
12. this.repository = repository;
13. }
14.
15. public String fetchCustomer() {
16. return repository.fetchCustomer(count);
17. }
18.
19. public String createCustomer() {
20. return repository.createCustomer();
21. }
22.
23. }
24.
CustomerRepository.java
1. package com.infy.repository;
2.
3. public class CustomerRepository {
4.
5. public String fetchCustomer(int count) {
6. return " The no of customers fetched are : " + count;
7. }
8.
9. public String createCustomer() {
10. return "Customer is successfully created";
11. }
12.
13. }
14.
Client.java
1. package com.infy;
2.
3. import
org.springframework.context.annotation.AnnotationConfigApplicationConte
xt;
4. import org.springframework.context.support.AbstractApplicationContext;
5. import com.infy.service.CustomerServiceImpl;
6. import com.infy.util.SpringConfiguration;
7.
8. public class Client {
9. public static void main(String[] args) {
10. CustomerServiceImpl service = null;
11. AbstractApplicationContext context = new
AnnotationConfigApplicationContext(SpringConfiguration.class);
12. service = (CustomerServiceImpl)
context.getBean("customerService");
13. System.out.println(service.fetchCustomer());
14. context.close();
15.
16. }
17. }
18.
Output:
Setter Injection
In Setter Injection, Spring invokes setter methods of a class to initialize the properties after invoking a
default constructor.
How can we use setter injection to inject values for the primitive type of properties?
Consider the below example to understand setter injection for primitive types.
Following the CustomerServiceImpl class has a count property, let us see how to initialize this property
during bean instantiation using the setter injection approach.
1. package com.infy.service;
2. public class CustomerServiceImpl implements CustomerService {
3. private int count;
4. public int getCount() {
5. return count;
6. }
7. public void setCount(int count) {
8. this.count = count;
9. }
10. public CustomerServiceImpl(){
11. }
12. }
1. package com.infy.util;
2. @Configuration
3.
4. public class SpringConfiguration {
5.
6.
7. @Bean // CustomerService bean definition using Setter Injection
8. public CustomerServiceImpl customerService() {
9. CustomerServiceImpl customerService = new
CustomerServiceImpl();
10. customerService.setCount(10);
11. return customerService;
12. }
13. }
Default constructor and setter methods of respective dependent properties are required in the
CustomerServiceImpl class. For setter injection, Spring internally uses the default constructor to
create a bean and then invokes a setter method of the respective property based on the name
attribute in order to initialize the values.
So far, we learned how to inject primitive values using setter injection in Spring.
1. package com.infy.service;
2. public class CustomerServiceImpl implements CustomerService
{
3. private CustomerRepository customerRepository;
4. private int count;
5.
6. public CustomerRepository getCustomerRepository() {
7. return customerRepository;
8. }
9.
10. public void setCustomerRepository(CustomerRepository
customerRepository) {
11. this.customerRepository = customerRepository;
12. }
13.
14. public int getCount() {
15. return count;
16. }
17.
18. public void setCount(int count) {
19. this.count = count;
20. }
21.
22. }
23.
1. package com.infy.util;
2. @Configuration
3.
4. public class SpringConfiguration {
5.
6. @Bean
7. public CustomerRepository customerRepository() {
8. return new CustomerRepository();
9. }
10.
11. @Bean // Setter Injection
12. public CustomerServiceImpl customerService() {
13. CustomerServiceImpl customerService = new
CustomerServiceImpl();
14. customerService.setCount(10);
15.
customerService.setCustomerRepository(customerRepository());
16. return customerService;
17. }
18. }
Highlights:
Demo Steps:
SpringConfiguration .java
1. package com.infy.util;
2.
3. import org.springframework.context.annotation.Bean;
4. import org.springframework.context.annotation.Configuration;
5. import com.infy.repository.CustomerRepository;
6. import com.infy.service.CustomerServiceImpl;
7.
8. @Configuration
9.
10. public class SpringConfiguration {
11.
12. @Bean // Setter Injection
13. public CustomerRepository customerRepository() {
14. CustomerRepository customerRepository = new
CustomerRepository();
15. return customerRepository;
16. }
17.
18. @Bean // Setter Injection
19. public CustomerServiceImpl customerService() {
20. CustomerServiceImpl customerService = new
CustomerServiceImpl();
21. customerService.setCount(10);
22. customerService.setRepository(customerRepository());
23. return customerService;
24. }
25. }
26.
CustomerService.java
1. package com.infy.service;
2.
3. public interface CustomerService {
4. public String fetchCustomer();
7.
CustomerServiceImpl.java
1. package com.infy.service;
2.
3. import com.infy.repository.CustomerRepository;
4.
5. public class CustomerServiceImpl implements CustomerService {
6.
7. private int count;
8. private CustomerRepository repository;
9.
10. public CustomerServiceImpl() {
11. }
12.
13. public void setCount(int count) {
14. this.count = count;
15. }
16.
17. public void setRepository(CustomerRepository repository) {
18. this.repository = repository;
19. }
20.
21. public String fetchCustomer() {
22. return repository.fetchCustomer(count);
23. }
24.
25. public String createCustomer() {
26. return repository.createCustomer();
27. }
28.
29. }
30.
CustomerRepository.java
1. package com.infy.repository;
2.
3. public class CustomerRepository {
4.
5. public String fetchCustomer(int count) {
6. return " The no of customers fetched are : " + count;
7. }
8.
9. public String createCustomer() {
14.
Client.java
1. package com.infy;
2.
3. import
org.springframework.context.annotation.AnnotationConfigApplicationConte
xt;
4. import org.springframework.context.support.AbstractApplicationContext;
5. import com.infy.service.CustomerServiceImpl;
6. import com.infy.util.SpringConfiguration;
7.
8. public class Client {
9. public static void main(String[] args) {
10. CustomerServiceImpl service = null;
11. AbstractApplicationContext context = new
AnnotationConfigApplicationContext(SpringConfiguration.class);
12. service = (CustomerServiceImpl)
context.getBean("customerService");
13. System.out.println(service.fetchCustomer());
14. context.close();
15. }
16. }
17.
Output:
Summary: DI
What is AutoScanning?
As discussed in the previous example as a developer you have to declare all the bean definition
in SpringConfiguration class so that Spring container can detect and register your beans as below
:
1. @Configuration
2. public class SpringConfiguration {
3. @Bean
4. public CustomerRepository customerRepository() {
5. return new CustomerRepository();
6. }
7. @Bean
8. public CustomerServiceImpl customerService() {
9.
10. return new CustomerServiceImpl();
11. }
12. }
Yes, Spring provides a way to automatically detect the beans to be injected and avoid even the
bean definitions within the Spring configuration file through Auto Scanning. In Auto Scanning,
Spring Framework automatically scans, detects, and instantiates the beans from the specified
base package, if there is no declaration for the beans in the SpringConfiguration class.
1. @Configuration
2. @ComponentScan(basePackages="com.infy")
3. public class SpringConfiguration {
4.
5. }
Component scanning isn’t turned on by default, however. You have to annotate the configuration class
with @ComponentScan annotation to enable component scanning as follows:
1. @Configuration
2. @ComponentScan
3. public class SpringConfiguration {
4. }
5.
In the above code, Spring will scan the package that contains SpringConfig class and it subpackages for
beans. But if you want to scan a different package or multiple packages then you can specify this with the
basePackages attribute as follows:
1. @Configuration
2. @ComponentScan(basePackages = "com.infy.service,com.infy.repository")
3. public class SpringConfiguration {
4. }
5.
Spring uses @ComponentScan annotation for the auto scan feature. It looks for classes with the
stereotype annotations and creates beans for such classes automatically.
Stereotype annotations denote the roles of types or methods at the conceptual level.
Stereotype annotations are @Component, @Service, @Repository,
and @Controller annotations.
These annotations are used for auto-detection of beans using @ComponentScan.
The Spring stereotype @Component is the parent stereotype.
The other stereotypes are the specialization of @Component annotation.
Annotation Usage
@Component It indicates the class(POJO class) as a Spring component.
@Service It indicates the Service class(POJO class) in the business layer.
It indicates the Repository class(POJO class in Spring DATA) in the
@Repository
persistence layer.
It indicates the Controller class(POJO class in Spring MVC) in the
@Controller
presentation layer.
1. @Component
2. public class CustomerLogging{
3. //rest of the code
4. }
5.
@Service - It is used to define a service layer Spring bean. It is a specialization of the @Component
annotation for the service layer.
1. @Service
2. public class CustomerSeviceImpl implements CustomerService {
3. //rest of the code
4. }
5.
1. @Repository
2. public class CustomerRepositoryImpl implements CustomerRepository {
3. //rest of the code
4. }
5.
1. @Controller
2. public class CustomerController {
3. //rest of the code
4. }
5.
By default, the bean names are derived from class names with a lowercase initial character. Therefore,
your above defined beans have the names customerController, customerServiceImpl, and
customerRepositoryImpl. It is also possible to give a specific name with a value attribute in those
annotations as follows:
1. @Repository(value="customerRepository")
2. public class CustomerRepositoryImpl implements CustomerRepository {
3. //rest of the code
4. }
Note: As a best practice, use @Service for the service layer, @Controller for the
Presentation layer, and @Repository for the Persistence layer.
Demo: AutoScanning
Highlights:
Demo Steps:
SpringConfiguration .java
1. package com.infy.util;
2.
3. import org.springframework.context.annotation.ComponentScan;
4. import org.springframework.context.annotation.Configuration;
5.
6. @Configuration
7. @ComponentScan(basePackages="com.infy")
8. public class SpringConfiguration {
9.
10. }
11.
CustomerService.java
1. package com.infy.service;
2.
3. public interface CustomerService {
4. public String fetchCustomer(int count);
5. public String createCustomer();
6. }
7.
CustomerServiceImpl.java
1. package com.infy.service;
2.
3. import org.springframework.beans.factory.annotation.Value;
4. import org.springframework.stereotype.Service;
5.
6. @Service("customerService")
7. public class CustomerServiceImpl implements CustomerService {
8.
9. @Value("10")
10. private int count;
11.
12. public String fetchCustomer(int count) {
13. return " The no of customers fetched are : " + count;
14. }
15.
21.
Client.java
1. package com.infy;
2.
3.
4. import
org.springframework.context.annotation.AnnotationConfigApplicationConte
xt;
5. import org.springframework.context.support.AbstractApplicationContext;
6. import com.infy.service.CustomerServiceImpl;
7. import com.infy.util.SpringConfiguration;
8.
9. public class Client {
10. public static void main(String[] args) {
11. CustomerServiceImpl service = null;
12.
13. AbstractApplicationContext context = new
AnnotationConfigApplicationContext(SpringConfiguration.class);
14. service = (CustomerServiceImpl)
context.getBean("customerService");
15.
16. System.out.println(service.createCustomer());
17. context.close();
18. }
19. }
20.
Output:
Summary : AutoScanning