Once we start learning Spring Framework, we hear a term โSpring Coreโ. Spring Core is nothing but an important and must know module of the Spring Framework. Without a deep learning of the Spring Core module, a developer shouldnโt think of working on Spring Framework confidently. This article on โSpring Core Tutorialsโ contains the must know artifacts for each developer who is going to work on Spring Framework based application.
Letโs discuss out topic โSpring Core Tutorialsโ and related concepts in detail.
Spring Core Tutorials
The Spring Core tutorials typically cover essential concepts and features of the Spring Framework, which plays an important role as the foundation for various other Spring projects and extensions. Here are some of the the key topics that often come under a Spring Core tutorial:
1) Introduction to Spring
2) Spring Container
3) Beans and their Configuration
7) Annotations
What is Spring Container?
Spring Container is itself a program in Spring Framework that manages the objects. The container gets its instructions by reading configuration metadata to instantiate, configure, and assemble the objects. We can represent configuration metadata in different forms, such as: XML, Java annotations, or Java code. Moreover, Spring Container has the following responsibilities:
1) Find and Scan Spring Beans
2) Create Objects for the beans that it found after scanning
3) Link/Inject objects if they have some relations such as HAS-A
4) Destroy the objects
What are the types Of Spring Containers?
As aforementioned, containers are itself a program. Spring Framework provides two Java Interfaces, that works as Spring Containers.
Bean Factory
It supports only XML configuration. It comes under package org.springframework.beans. Now it is supposed as a legacy container. Since we canโt create an object from an Interface in Java, the BeanFactory interface provides a most commonly used implementation class which is XmlBeanFactory.
ApplicationContext
It supports all the forms of configuration: XML, Java and Annotation. It comes under package org.springframework.context. ApplicationContext provides multiple implementation classes such as:
(A) ClassPathXmlApplicationContext : We should use it when configuration file is at projectโs class path.
(B) FileSystemXmlApplicationContext : We should use it when configuration file is at serverโs file system.
(C) AnnotationConfigApplicationContext : We should use it when we are using annotation-based configuration.
How to create a Spring Container?
Letโs see how we can create a Spring container programmatically. Since ApplicationContext is the most widely used and BeanFactory is rarely used, we will make use of ApplicationContext.
ApplicationContext context = new ClassPathXmlApplicationContext("com/dev/spring/example/config.xml");
In the above line of code, we are using ClassPathXmlApplicationContext to create the container context and supplying configuration file named as config.xml (For XML-based configuration).
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
In the above line of code, we are using AnnotationConfigApplicationContext to create the container context and supplying configuration class named as AppConfig.class (For Annotation-based configuration).
How to get Bean from Spring Container?
Spring Container (BeanFactory/ApplicationContext)ย provides getBean() method to get bean from it. However, getBean() method has multiple flavors as it has got different combination of parameters. We can use any one of them as per our requirement. Below is the step to get bean from Spring Container.
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/dev/spring/example/config.xml"); Person person = ctx.getBean(Person.class); System.out.println(person);
Here, Person is the name of defined class.
What is a Spring Bean?
Spring Bean is a class in spring, which follows the rules provided by the Spring Container. Below are the rules that Spring Container expects from developers to follow while creating a class that will act as a bean:
1) Class must be public.
2) Variables are recommended to be private.
3) Methods should be public.
4) Class should be under a package. It can be either under a base package or its sub package.
5) Provide any one of the two combinations given below. There is no harm in providing both of them, but any one will be sufficient.
(A) Default constructor withย setter & getter methods
(B) Parameterized constructor
6) Class can extend or implement only those classes or interfaces which are part of Spring Frameworkโs API. We can identify classes and interfaces from Spring Framework API by finding their package names. They come under package org.springframework.
7) Class can override 3 methods from Object class: toString(), hashcode() and equals().
8) Class can implement java.io.Serializable interface.
9) Class can use Core Java Annotations, Spring Framework Annotations, and some Integration Annotations. Core Java annotations comes under package java.lang, such as Deprecated, Override, SafeVarargs, SupressWarnings. Integration annotations are used in very rare cases.
What inputs a Spring container requires from a Programmer to create Objects?
Spring container requires two inputs from a programmer to create an object: Spring Bean & Spring Configuration. As aforementioned, Spring Bean is a specific type of class that follows rules provided by the Spring Container. Spring configuration generally contains the name of the bean, linking details with other beans and some other information if any. Spring Configuration is also known as Configuration metadata.
Furthermore, Spring Configuration can be in any of the three forms:
1) XML-based Configuration
2) Java-based Configuration
3) Annotation-based Configuration
Please note that annotation configuration is the most popular and highly used in the industry now-a-days. Spring Boot has already removed the XML configuration.
What are the different ways to provide Configuration Metadata?
As mentioned above, there are three ways of Configuration metadata that a developer provides to Spring Container. Letโs discuss about them one by one. Developer need to create Spring configuration metadata to tell Spring container how to initialize, configure, wire and assemble the application specific beans. Please note that this is very important topic for every developer under โSpring Core Tutorialsโ.
XML-based Configurationย
In Spring Framework, developer defines the bean name, dependencies and the other services needed by Spring Container. If these details are specified in configuration files which are in XML format, it is known as XML-based configuration. These configuration files usually contain a lot of bean definitions and other required application-specific configuration options. They generally start with a bean tag. All configurations can be in one or multiple XML files. For example, below code snippet demonstrates the XML-based configuration.
<bean id="employeeBean" class="com.dev.spring.EmployeeBean"> <property name="name" value="employee1"/> <property name="age" value="24"/> </bean>
Annotation-based Configuration
Spring 2.5 introduces annotation-based configuration. By default, annotation wiring is not turned on in the Spring framework. So, in order to use annotation-based configuration, we need to enable it before using it by specifying <context:annotation-config/> tag as shown below. Once this tag is configured, we can start annotating our code.
<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans>
Note: Since Spring Boot has reduced the use of XML configurations, we donโt need to follow this step in Spring Boot Application. We can directly use annotations whenever it is required.ย
Furthermore, in order to make a class as a bean, we need to apply an annotation on the top of the class. There are various annotations that we can apply on top of the class, such as @Component, @Controller, @Service, @Repository etc. Most of the time we apply @Component annotation as it is the basic annotation. However, other annotations have some specific purpose. For example, below code snippet demonstrates the concept.ย
@Component public class Employee{ ย ย private Long id; private String name; private String department; }
During the application startup, Spring parses the @Component annotated classes and creates bean definitions, considering that this class acts as a spring bean. In the above example, after the application startup, an instance ofย Employee will live as a bean in the Spring Container (ApplicationContext).
Now in order to know which annotations we can apply in spring beans, you can visit a separate article on Spring Bean Annotations.
Java-based Configuration
Starting with Spring 3.0, a pure-Java configuration container was provided. We donโt need any XML with this method of configuration. The key features in Spring Frameworkโs new Java-configuration support are @Configuration annotated classes and @Bean annotated methods. Using @Configuration annotation represents that Spring container will use it as a source of Beans definitions. Using the @Bean tells Spring container that method will return an object which should be registered as a bean in Spring application context.
1. @Beanย annotation plays the same role as theย <bean/>ย element.
2. @Configuration classes allow define inter-bean dependencies by simply calling otherย @Bean methods in the same class.
For example, below code demonstrates the concept of Java-based configuration:
@Configuration public class EmployeeConfig{ @Bean public EmployeeBean permanentEmployee(){ return new EmployeeBean(); } @Bean(name="contractEmployee") public EmployeeBean otherEmployee(){ return new EmployeeBean(); } }
Here, method name becomes the bean id by default. However, we can provide the name of bean as per our choice by specifying โnameโ attribute of @Bean annotation as shown above.
How to create your first Spring Application using XML Configuration?
After going through the concept, now its time to create our fist Spring Application using XML configuration. Letโs follow below steps to create our first spring application:
Steps to develop Spring Application Using XML Configuration
There are certain steps to develop a Spring Application Using XML Configuration as below:
1) Create a simple maven project using an IDE of your choice, such as Eclipse, STS, NetBeans, IntelliJ etc.
2) Add maven dependencies for Spring to support core and context modules.
3) Create a POJO class.
4) Create an XML Configuration file and define a bean for your POJO class.
5) Create a Test class with main() method. In main() method, create a spring container and retrieve the bean.
6) Select the Test class, Run it as a Java Application and see the results.
Step#1: Create a Simple Maven Project in Eclipse/STS
1) Open your Eclipse IDE, then go to new -> project-> Maven Project and click on next.
2) Click on โCreate a simple Project (Skip archetype selection)โ
3) Provide the values of Group Id & Artifact Id. Group Id uniquely identifies your project among all. So it may be something like com.dev.spring.example. Artifact Id may be something like project name, so here we can put artifact id as SpringFirstExample.
4) Click on โFinishโ. You will get a new maven based project.
Step#2: Modify pom.xml
When you create a new project, you will find a file called pom.xml. In this file we need to provide the dependency of basic spring jars. Copy the below code and paste it in your pom.xml inside <dependencies> tag. You can choose to provide the latest stable version of your own choice.
<dependency> ย ย ย <groupId>org.springframework</groupId> ย ย ย <artifactId>spring-core</artifactId> ย ย ย <version>4.1.4.RELEASE</version> </dependency> <dependency> ย ย <groupId>org.springframework</groupId> ย ย <artifactId>spring-context</artifactId> ย ย <version>4.1.4.RELEASE</version> </dependency>
Once you save the pom.xml file, all required jars will get downloaded automatically.
Step#3: Create a Pojo Classย
Letโs create a package com.dev.spring.core.example inside โsrc/main/javaโ folder of your project explorer. Then create a POJO class Book.java under this package as shown below.
package com.dev.spring.core.example; public class Book { private Integer id; private String name; public Book() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Book [Id=" + Id + ", name=" + name + "]"; } }
Here, we have overridden toString() just to print the values from our object.
Step#4: Create a configuration file (config.xml)
This file is important as we are using XML method to provide bean definition.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <bean name="book" class="com.dev.spring.core.example.Book"> ย <property name="id" value="94568"/> <property name="name" value="Spring In Action"/> </bean> </beans>
While creating XML configuration file, we can referย Spring docs for XSD Configurationย to get the proper schema definitions. Since we are going to use beans & context module of Spring framework, we have added schema definitions only for them.
Step#5: Create a Test class
Letโs create a test class where we will define a main() method to test our results.
package com.dev.spring.core.example; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/core/example/config.xml"); Book book = ctx.getBean(Book.class); System.out.println(book); } }
The above code demonstrates the creation of Spring Container (ApplicationContext in our case), and retrieval of bean.
Step#6: Test Output
Once you run the application, output will look like below:
Book [Id=94568, name=Spring In Action]
If you get above result after test, it means your project has run successfully.
How to create your first Spring Application using Annotation based Configuration?
After going through the concept, now its time to create our fist Spring Application using Annotation configuration. Letโs follow below steps to create our first spring application:
Steps to develop Spring Application Using Annotation Based Configuration
There are certain steps to develop a Spring Application Using Annotation Based Configuration as below:
1) Create a simple maven project using an IDE of your choice, such as Eclipse, STS, NetBeans, IntelliJ etc.
2) Add maven dependencies for Spring to support core and context modules.
3) Create a POJO class. Annotate this class with @Component.
4) Create an XML Configuration file. Provide <context:component-scan base-package=โ โ/> tag under </beans> tag to let spring container scan the classes which are annotated with @Component.
5) Create a Test class with main() method. In main() method, create a spring container and retrieve the bean.
6) Select the Test class, Run it as a Java Application and see the results.
Step#1: Create a Simple Maven Project in Eclipse/STS
1) Open your Eclipse IDE, then go to new -> project-> Maven Project and click on next.
2) Click on โCreate a simple Project (Skip archetype selection)โ
3) Provide the values of Group Id & Artifact Id. Group Id uniquely identifies your project among all. So it may be something like com.dev.spring.example. Artifact Id may be something like project name, so here we can put artifact id as SpringFirstExample.
4) Click on โFinishโ. You will get a new maven based project.
Step#2: Modify pom.xml
When you create a new project, you will find a file called pom.xml. In this file we need to provide the dependency of basic spring jars. Copy the below code and paste it in your pom.xml inside <dependencies> tag. You can choose to provide the latest stable version of your own choice.
<dependency> ย ย ย <groupId>org.springframework</groupId> ย ย ย <artifactId>spring-core</artifactId> ย ย ย <version>4.1.4.RELEASE</version> </dependency> <dependency> ย ย <groupId>org.springframework</groupId> ย ย <artifactId>spring-context</artifactId> ย ย <version>4.1.4.RELEASE</version> </dependency>
Once you save the pom.xml file, all required jars will get downloaded automatically.
Step#3: Create a Pojo Classย
Letโs create a package com.dev.spring.core.example inside โsrc/main/javaโ folder of your project explorer. Then create a POJO class Book.java under this package as shown below.
package com.dev.spring.core.example; @Component public class Book { private Integer id; private String name; public Book() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Book [Id=" + Id + ", name=" + name + "]"; } }
Here, we have overridden toString() just to print the values from our object.
Step#4: Create a configuration file (config.xml)
We need to specify <context:component-scan base-package=โcom.dev.spring.bean.lifecycleโ/>ย tag here. It will scan the classes under the given package in the application in order to instantiate the bean.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- bean definitions not required as we will use @Component Annotation -->
<context:component-scan base-package="com.dev.spring.core.example"/>
</beans>
While creating XML configuration file, we can referย Spring docs for XSD Configurationย to get the proper schema definitions. Since we are going to use beans & context module of Spring framework, we have added schema definitions only for them.
Step#5: Create a Test class
Letโs create a test class where we will define a main() method to test our results.
package com.dev.spring.core.example; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/core/example/config.xml"); Book book = ctx.getBean(Book.class); book.setId(95468); book.setName("Spring In Action"); System.out.println(book); } }
The above code demonstrates the creation of Spring Container (ApplicationContext in our case), and retrieval of bean.
Step#6: Test Output
Once you run the application, output will look like below:
Book [Id=94568, name=Spring In Action]
If you get above result after test, it means your project has run successfully.
How to create your first Spring Application using Java based Configuration?
After going through the concept, now its time to create our fist Spring Application using Java based configuration. In this method, we will get rid of XML completely. Letโs follow below steps to create our first spring application:
Steps to develop Spring Application Using Java Based Configuration
There are certain steps to develop a Spring Application Using Annotation Based Configuration as below:
1) Create a simple maven project using an IDE of your choice, such as Eclipse, STS, NetBeans, IntelliJ etc.
2) Add maven dependencies for Spring to support core and context modules.
3) Create a POJO class.
4) Create an AppConfig Configuration class. Annotate this class with @Configuration and methods with @Bean. This java class will act as XML configuration class completely. Hence, we donโt need to create any XML file this time.e need
5) Create a Test class with main() method. In main() method, create a spring container and retrieve the bean. In order to create Spring Container, use AnnotationConfigApplicationContext in place of ClassPathXmlApplicationContext.
6) Select the Test class, Run it as a Java Application and see the results.
Step#1: Create a Simple Maven Project in Eclipse/STS
1) Open your Eclipse IDE, then go to new -> project-> Maven Project and click on next.
2) Click on โCreate a simple Project (Skip archetype selection)โ
3) Provide the values of Group Id & Artifact Id. Group Id uniquely identifies your project among all. So it may be something like com.dev.spring.example. Artifact Id may be something like project name, so here we can put artifact id as SpringFirstExample.
4) Click on โFinishโ. You will get a new maven based project.
Step#2: Modify pom.xml
When you create a new project, you will find a file called pom.xml. In this file we need to provide the dependency of basic spring jars. Copy the below code and paste it in your pom.xml inside <dependencies> tag. You can choose to provide the latest stable version of your own choice.
<dependency> ย ย ย <groupId>org.springframework</groupId> ย ย ย <artifactId>spring-core</artifactId> ย ย ย <version>4.1.4.RELEASE</version> </dependency> <dependency> ย ย <groupId>org.springframework</groupId> ย ย <artifactId>spring-context</artifactId> ย ย <version>4.1.4.RELEASE</version> </dependency>
Once you save the pom.xml file, all required jars will get downloaded automatically.
Step#3: Create a Pojo Classย
Letโs create a package com.dev.spring.core.example inside โsrc/main/javaโ folder of your project explorer. Then create a POJO class Book.java under this package as shown below.
package com.dev.spring.core.example; public class Book { private Integer id; private String name; public Book() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Book [Id=" + Id + ", name=" + name + "]"; } }
Here, we have overridden toString() just to print the values from our object.
Step#4: Create a configuration class as AppConfig.javaย
We need to create a Configuration class AppConfig.java. Apply @Configuration at class level and @Bean at method levels as shown below:
package com.dev.spring.core.example; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public Person getPerson() { return new Person(); } }
Note: When you create a bean using @Bean as above, the object will be created within Singleton scope. Additionally, this method (getPerson() in our case) will execute automatically during pre-instantiation of spring bean. Hence, there will only one object be created, no matter how many times you try to instantiate it.
Step#5: Create a Test class
Letโs create a test class where we will define a main() method to test our results. This time we will use AnnotationConfigApplicationContext to create Spring Container context in place of ClassPathXmlApplicationContext.
package com.dev.spring.core.example; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Test { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); Book book = ctx.getBean(Book.class); book.setId(95468); book.setName("Spring In Action"); System.out.println(book); } }
The above code demonstrates the creation of Spring Container (ApplicationContext in our case), and retrieval of bean.
Step#6: Test Output
Once you run the application, output will look like below:
Book [Id=94568, name=Spring In Action]
If you get above result after test, it means your project has run successfully.
FAQ
Letโs discuss FAQs under the Spring Core Tutorials.
When to use BeanFactory container vs. ApplicationContextContainer?
If you are using small scale, light weight spring based application, prefer using BeanFactory container as it takes less memory to work. In other words, if there is a memory limitation in place, prefer using BeanFactory container. For example, mobile apps, embedded system apps, IOT apps etc.
In all other heavy weight apps where memory limitation is not in place, such as web apps, enterprise apps, distributed apps, desktop apps etc., prefer using ApplicationContext container.
In general practice, we should prefer using ApplicationContext container wherever it is possible to use. You must have a genuine reason of not using ApplicationContext Container.