This Markdown file contains all the Spring Boot examples you provided, demonstrating Dependency Injection (DI), Bean creation, and Spring annotations. Explanations are included for beginners.
- Spring Boot: Framework to create stand-alone, production-grade Spring applications easily.
- Bean: An object managed by the Spring container.
- @Component: Marks a class as a Spring-managed component.
- @Autowired: Automatic dependency injection.
- @Bean: Method-level annotation for bean creation in configuration classes.
- @Configuration: Marks a class as a source of bean definitions.
- @Qualifier: Selects a specific bean when multiple beans of the same type exist.
- @Primary: Marks a bean as the default when multiple candidates exist.
- Field Injection: Injecting dependencies directly into fields.
- Setter Injection: Injecting dependencies via setter methods.
- Constructor Injection: Injecting dependencies via constructors.
package com.training.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.training.lms.app.Product;
@Component
public class Order {
@Autowired
Product product;
public Order() {
System.out.println("Order is created");
}
public Product getProduct() {
return product;
}
}Explanation: Field injection is used to inject Product. When Spring creates Order, it prints a message.
@SpringBootApplication(scanBasePackages = {"com.training.app","com.training.lms"})
public class SpringBootFirstApplication {
private final Student student;
SpringBootFirstApplication(Student student) {
this.student = student;
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringBootFirstApplication.class, args);
Student student = context.getBean("student", Student.class);
System.out.println(student);
Order order = context.getBean("order", Order.class);
System.out.println(order.getProduct());
}
@Bean
public Student Student2() {
System.out.println("Creating Student 2 via Bean Method");
return new Student();
}
}Explanation: Demonstrates Spring Boot main class, bean creation, and dependency injection.
@Component
public class Product {
public Product() {
System.out.println("Product is Created");
}
}Explanation: Component class; Spring manages its lifecycle.
@Configuration
public class SpringBeansConfiguration {
@Bean
public Product product1() {
System.out.println("Product is created via bean Method");
return new Product();
}
}Explanation: Shows Java-based bean creation via @Configuration and @Bean.
public class DeliveryDetails {
public DeliveryDetails() {
System.out.println("DeliveryDetails is created......");
}
}
public class SpringXMLWithBoot {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
}
}Explanation: Demonstrates non-Spring managed class and XML-based Spring bean loading.
@Component("cartItems1")
public class CartItems {
private int noOfItems;
private ArrayList<String> itemNames;
// getters, setters, constructors
}
@Component
public class OrderDetails {
@Autowired
private CartItems cartItems;
private double orderAmount;
private String userEmail;
// getters, setters
}Explanation: Shows field injection and multiple ways to define beans.
@Component
public class Product { /* properties, constructors, getters, setters */ }
@Component
public class Order {
@Autowired
public void setProduct(@Qualifier("productTwo") Product product) {
this.product = product;
}
}
@Component
public class OrderDelivery {
@Autowired
private Order order;
}
@Configuration
public class SpringConfigurationBeans {
@Bean("productTwo")
public Product getProduct() { return new Product(); }
}Explanation: Setter injection and configuration-based bean creation.
@Component
public class Order {
public Order(@Autowired @Qualifier("productOne") Product product) {
this.product = product;
}
}Explanation: Constructor injection allows injecting dependencies through constructor parameters.
public interface Vehicle { String VehicleType(); }
@Primary
@Component
public class Car implements Vehicle { ... }
@Component
public class Bike implements Vehicle { ... }
@Component
public class Bus implements Vehicle { ... }
@Component
public class Garrage {
@Autowired
private Vehicle vehicle;
}Explanation: Demonstrates interface injection and usage of @Primary for default bean selection.
- Spring manages objects: Components and beans are automatically instantiated.
- Dependency Injection: Avoid manual object creation; Spring injects dependencies.
- Bean Identification: Use
@Qualifierand@Primaryto resolve conflicts. - Different DI methods: Field, setter, and constructor injections.
- Configuration flexibility: Beans can be defined via annotations, Java configuration, or XML.
This project demonstrates Spring Boot's configuration and dependency injection using @Value, @Autowired, and @PropertySource annotations. It loads configuration values from external property files and injects them into beans.
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.PropertySource;
import com.training.springboot.beans.AwsDatabaseConfiguration;
import com.training.springboot.beans.DatabaseCofiguration;
import com.training.springboot.beans.EmailsCrdentialsConfiguration;
import com.training.springboot.beans.org.OrganizationInfo;
@PropertySource("aws-database.properties") // Loads additional property file
@SpringBootApplication // Enables Spring Boot auto-configuration and component scanning
public class Application {
public static void main(String[] args) {
// Starts the Spring Boot application and returns the application context
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// Fetching Database configuration bean
DatabaseCofiguration cofiguration = context.getBean("databaseCofiguration", DatabaseCofiguration.class);
System.out.println(cofiguration.getPort());
System.out.println(cofiguration.getUrl());
System.out.println(cofiguration.getUserName());
System.out.println(cofiguration.getPassword());
System.out.println(cofiguration.getAppName());
System.out.println(cofiguration.getDbProfile().getUrl());
// Fetching Email configuration bean
System.out.println("******* Email Data ****");
EmailsCrdentialsConfiguration emailConfig = context.getBean("emailsCrdentialsConfiguration", EmailsCrdentialsConfiguration.class);
System.out.println(emailConfig.getEmailHost());
System.out.println(emailConfig.getEmailId());
System.out.println(emailConfig.getPassword());
// Fetching Organization Info bean
System.out.println("***** Org Data ******");
OrganizationInfo info = context.getBean("organizationInfo", OrganizationInfo.class);
System.out.println(info.getOrgEmpCount());
info.getDeptNames().forEach(System.out::println);
// Fetching AWS Database Configuration bean
System.out.println("******************************");
AwsDatabaseConfiguration awsConfig = context.getBean("awsDatabaseConfiguration", AwsDatabaseConfiguration.class);
System.out.println(awsConfig.getAwsUserName());
System.out.println(awsConfig.getAwsPassword());
System.out.println(awsConfig.getAwsHost());
}
}@SpringBootApplication: Combines@Configuration,@EnableAutoConfiguration, and@ComponentScan.@PropertySource: Loads properties from an external file (e.g.,aws-database.properties).ConfigurableApplicationContext: Used to access beans created by Spring.
package com.training.springboot.beans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AwsDatabaseConfiguration {
@Value("${aws.db.url}")
private String awsHost;
@Value("${aws.db.user.name}")
private String awsUserName;
@Value("${aws.db.password}")
private String awsPassword;
// Getters and Setters
}- Injects AWS database details from the property file.
- Uses
@Valueto bind property keys to Java fields.
Example in aws-database.properties:
aws.db.url=aws.amazonserver.com
aws.db.user.name=aws_user
aws.db.password=aws_passpackage com.training.springboot.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class DatabaseCofiguration {
@Value("${db.port.number}")
private int port;
@Value("${db.url}")
private String url;
@Value("${db.username}")
private String userName;
@Value("${db.password}")
private String password;
@Value("${spring.application.name}")
private String appName;
@Autowired
private DbProfile dbProfile; // Injects another bean
public DatabaseCofiguration() {
System.out.println("Db is created...");
}
// Getters and Setters
}- Demonstrates field injection using
@Value. - Uses
@Autowiredto inject another bean (DbProfile). - Useful when multiple configuration sources exist.
Example in application.properties:
db.port.number=1521
db.url=localhost:1521:xe
db.username=root
db.password=root
spring.application.name=SpringBootConfigDemopackage com.training.springboot.beans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("production")
public class DbProfile {
@Value("${db.url}")
private String url;
// Getter and Setter
}- Defines a profile-specific database URL.
@Component("production")gives a custom bean name.
package com.training.springboot.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class EmailsCrdentialsConfiguration {
private String emailHost;
@Value("${app.mail.user}")
private String emailId;
private String password;
@Autowired
private DatabaseCofiguration databaseCofiguration;
public EmailsCrdentialsConfiguration(@Value("${app.mail.host}") String emailHost) {
this.emailHost = emailHost;
}
@Value("${app.mail.password}")
public void setPassword(String password) {
System.out.println("setEmailPassword");
this.password = password;
}
// Getters and Setters
}- Shows constructor injection, setter injection, and field injection.
- Demonstrates multiple ways to inject values using
@Value.
Example in application.properties:
app.mail.host=smtp.gmail.com
app.mail.user=test@gmail.com
app.mail.password=test123package com.training.springboot.beans.org;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class OrganizationInfo {
@Value("${org.emp.count:55}") // default value if key is missing
private int orgEmpCount;
@Value("${org.dept.names}")
private List<String> deptNames;
// Getters and Setters
}- Injects list values directly from the property file.
- Uses default value
55when key is not present.
Example in application.properties:
org.emp.count=120
org.dept.names=HR,Finance,IT,Sales| Concept | Annotation Used | Description |
|---|---|---|
| External Configuration | @Value, @PropertySource |
Injects property values into fields |
| Bean Creation | @Component |
Marks class as a Spring-managed bean |
| Dependency Injection | @Autowired |
Automatically injects dependent beans |
| Constructor Injection | @Value in constructor |
Provides value at object creation |
| Setter Injection | @Value on setter |
Sets value using setter method |
| Lists and Defaults | @Value with default |
Handles multiple values and fallbacks |
✅ This example is perfect for beginners who want to learn how to use @Value, @Autowired, and property files in Spring Boot. It shows all major injection techniques in one practical example.
This example demonstrates how Spring Boot manages beans, their scopes, and how dependency injection (DI) works using annotations like @Autowired, @Bean, @Component, and @Scope.
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import com.training.springboot.beans.Order;
import com.training.springboot.beans.Product;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// Getting Product bean from container
Product product = context.getBean("product", Product.class);
System.out.println(product);
// Again fetching same bean to check if it creates a new instance or not
Product product2 = context.getBean("product", Product.class);
System.out.println(product2);
// Getting Order bean which has Product injected
Order order = context.getBean("order", Order.class);
System.out.println(order);
System.out.println(order.getProduct());
Order order1 = context.getBean("order", Order.class);
System.out.println(order1);
System.out.println(order1.getProduct());
// DI : Is it created a new Product to inject in Order? → No (because singleton)
System.out.println("*********************** 2nd Product **** ");
Product product3 = context.getBean("product2", Product.class);
System.out.println(product3);
}
// Creating another Product bean manually using @Bean
@Bean
Product product2() {
return new Product();
}
}- Bean: An object managed by Spring’s IoC container.
- IoC (Inversion of Control): Spring creates and manages objects for you.
- DI (Dependency Injection): Injecting one bean into another automatically (e.g., Product into Order).
- ApplicationContext: Spring container that holds and manages beans.
- When a bean is requested with
context.getBean(), Spring returns it from the container. - If the bean scope is singleton (default), the same object reference is returned every time.
- If the scope is prototype, a new object is created on each request.
package com.training.springboot.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Order {
@Autowired
private Product product; // Dependency Injection
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}@Component: Marks the class as a Spring bean.@Autowired: Automatically injects a matching bean (here,Product) from the container.- When Spring creates an
Orderbean, it automatically sets itsproductfield.
package com.training.springboot.beans;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//@Scope(value = "prototype") // Uncomment to test prototype behavior
@Component
public class Product {
private int productId;
private String productName;
private double price;
public Product() {
super();
System.out.println("Product one is created");
}
// Getters and Setters
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}- By default, beans in Spring are singleton.
- The
Productconstructor prints a message each time it is created — helping us see when new objects are made. - Uncomment
@Scope("prototype")to make a new Product each time it’s requested.
Spring provides 5 main bean scopes:
| Scope | Description |
|---|---|
| singleton (default) | Only one instance per Spring container. Same object shared everywhere. |
| prototype | A new bean instance is created each time it is requested. |
| request | One bean per HTTP request (used in web apps). |
| session | One bean per HTTP session (used in web apps). |
| application | One bean for the entire application lifecycle. |
| webSocket | One bean per WebSocket session. |
@Scope("singleton") // default scope
@Component
public class Product {}
@Scope("prototype")
@Component
public class Order {}When Spring manages a bean, it goes through 4 main phases:
- Construction – Bean object is created.
- Configuration – Dependencies are injected (like
@Autowired). - Utilization – Bean is used for business logic.
- Destruction – Bean is destroyed when the container shuts down.
| Concept | Explanation |
|---|---|
| Bean | Object managed by Spring container |
| Scope | Defines how many instances of the bean exist |
| DI (Dependency Injection) | Injecting dependent beans automatically |
| Singleton Scope | Only one bean instance for the entire app |
| Prototype Scope | Creates a new instance every time you request the bean |
| @Autowired | Automatically wires dependent beans |
| @Bean | Defines a bean method manually in a configuration class |
If you see the same memory reference printed for two beans, it means singleton scope is active. Different references mean prototype scope is used.
This explanation helps beginners clearly understand how Spring Boot creates and injects beans, how scopes affect object creation, and how the lifecycle of a bean works in simple, real-world terms.
In Spring Boot, every object managed by the Spring Container is called a Bean.
The container controls its creation, initialization, and destruction — this process is known as the Bean Lifecycle.
This example demonstrates:
- How beans are created and managed by Spring Boot
- The difference between annotations and configuration-based bean definitions
- How to handle initialization and destruction phases
- The difference between
singletonandprototypescope
com.training.springboot
├── Application.java
└── databse
├── DatabaseConnection.java
├── EmailConnection.java
└── SprinBeansConfiguration.java
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.training.springboot.databse.DatabaseConnection;
import com.training.springboot.databse.EmailConnection;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// Retrieving beans from container
DatabaseConnection databaseConnection = context.getBean("databaseConnection", DatabaseConnection.class);
System.out.println(databaseConnection);
DatabaseConnection databaseConnection2 = context.getBean("databaseConnection", DatabaseConnection.class);
System.out.println(databaseConnection2);
EmailConnection emailConnection = context.getBean("emailConnection", EmailConnection.class);
System.out.println(emailConnection);
EmailConnection emailConnection2 = context.getBean("emailConnection2", EmailConnection.class);
System.out.println(emailConnection2);
}
}@SpringBootApplication: Marks the main class as the Spring Boot entry point.SpringApplication.run(...): Starts the application and initializes the Spring context.context.getBean(...): Fetches a bean managed by the Spring container.
Output shows:
👉 Singleton beans return the same object reference.
👉 Prototype beans return different object references.
package com.training.springboot.databse;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//@Scope("prototype")
@Component
public class DatabaseConnection implements InitializingBean, DisposableBean {
@Value("localhost:1521")
private String url;
private String userName;
private String password;
public DatabaseConnection() {
System.out.println("Database is created");
}
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getUserName() { return userName; }
@Value("root")
public void setUserName(String userName) {
System.out.println("Setting the value of username");
this.userName = userName;
}
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("This is afterPropertiesSet() call — Bean initialized");
}
@Override
public void destroy() throws Exception {
System.out.println("Releasing resources — Bean destroyed");
}
}| Term | Description |
|---|---|
| @Component | Marks this class as a Spring-managed bean |
| @Value | Injects literal values into bean fields |
| InitializingBean | Interface used to execute logic after bean properties are set |
| DisposableBean | Interface used to execute logic before bean destruction |
| @Scope("prototype") | Creates a new instance of the bean each time it’s requested (default is singleton) |
package com.training.springboot.databse;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
@Component
public class EmailConnection {
public EmailConnection() {
System.out.println("Email is created");
}
@PostConstruct
public void logicBeanCreation() {
System.out.println("This is life cycle method: After Construction and Configuration");
}
@PreDestroy
public void logicOnBeanDestruction() {
System.out.println("This is life cycle method: Before Destruction");
}
public void email2LifeCycle() {
System.out.println("email2LifeCycle..............");
}
public void email2LifeCycleDestroy() {
System.out.println("email2LifeCycleDestroy.................................");
}
}| Annotation | Description |
|---|---|
| @PostConstruct | Runs immediately after the bean is created and dependencies are injected |
| @PreDestroy | Runs right before the bean is destroyed |
| @Component | Registers the class as a Spring-managed component |
package com.training.springboot.databse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SprinBeansConfiguration {
@Bean(initMethod = "email2LifeCycle", destroyMethod = "email2LifeCycleDestroy")
public EmailConnection emailConnection2() {
return new EmailConnection();
}
@Bean
public EmailConnection emailConnection3() {
return new EmailConnection();
}
}- @Configuration — tells Spring that this class provides bean definitions.
- @Bean — manually creates and registers beans in the container.
- initMethod / destroyMethod — specify custom initialization and cleanup methods.
Here’s how the Bean Lifecycle works:
| Phase | Description | Method/Annotation |
|---|---|---|
| 1️⃣ Creation | Object is created (constructor called) | Constructor |
| 2️⃣ Dependency Injection | Values are injected (@Value, @Autowired) | - |
| 3️⃣ Initialization | Custom logic after dependencies are set | afterPropertiesSet() / @PostConstruct |
| 4️⃣ Ready to Use | Bean is available for use | - |
| 5️⃣ Destruction | Cleanup before bean is removed | destroy() / @PreDestroy |
| Feature | Singleton | Prototype |
|---|---|---|
| Instances | Only one per Spring container | New instance for each request |
| Default Scope | ✅ Yes | ❌ No |
| Lifecycle Management | Fully managed by container | Only initialization managed |
| Example Use Case | Service / Repository | Temporary objects or DTOs |
To make a bean prototype, uncomment:
@Scope("prototype")Database is created
Setting the value of username
This is afterPropertiesSet() call — Bean initialized
Email is created
This is life cycle method: After Construction and Configuration
Email is created
email2LifeCycle..............
| Concept | Key Idea |
|---|---|
| Spring Container | Manages creation, initialization, and destruction of beans |
| Bean Lifecycle | Sequence of events from creation → use → destruction |
| @PostConstruct & @PreDestroy | Annotation-based lifecycle management |
| InitializingBean & DisposableBean | Interface-based lifecycle management |
| @Bean (initMethod/destroyMethod) | Java config-based lifecycle management |
| @Scope("prototype") | Creates multiple bean instances |
| Default scope | Singleton |
✅ Learning Tip:
When learning Spring Boot Bean lifecycle:
- Start with
@Componentand understand how Spring creates beans. - Then add lifecycle interfaces (
InitializingBean,DisposableBean). - Finally, move to annotations (
@PostConstruct,@PreDestroy) and configuration-based beans.
Author: Raushan Singh
Topic: Spring Boot – Bean Lifecycle and Scope
Level: Beginner → Intermediate → Advanced
This section explains Spring Boot Runners — a powerful feature that allows developers to execute specific logic right after the application starts. It includes full code examples and beginner-to-advanced explanations.
Runners are special classes that execute immediately after the Spring Boot application context has been initialized (i.e., after SpringApplication.run() completes).
They are typically used for:
- Initializing configuration data.
- Connecting to external systems (like sending notifications, emails, etc.).
- Executing startup logic only once when the app boots.
Spring Boot provides two types of runners:
- CommandLineRunner → Access command-line arguments as a
String... argsarray. - ApplicationRunner → Access command-line arguments as an
ApplicationArgumentsobject (structured form).
Both interfaces have a single abstract method called run() which is automatically executed at application startup.
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.training.springboot.beans.Product;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
System.out.println("Args size :" + args.length);
System.out.println("Args value :" + args);
for (String arg : args) {
System.out.println(arg);
}
System.out.println("Before Run Method");
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println("After Run Method");
Product product = context.getBean(Product.class);
System.out.println(product);
}
}- The application prints command-line arguments.
- It initializes the Spring context.
- Runners (explained below) are executed automatically after
SpringApplication.run().
CommandLineRunner is a functional interface with one method:
void run(String... args) throws Exception;- It receives command-line arguments as a String array.
- Executes once right after the application starts.
package com.training.springboot.runners;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Component
public class EmailNotificationRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
for (String arg : args) {
System.out.println(arg);
}
System.out.println("This is CommandLineRunner...");
System.out.println("Application is ready to operate.");
System.out.println("Sending email to developer...");
System.out.println("Email successfully sent!");
}
public void runAnother() {
System.out.println("This is not part of Spring Boot runner method");
}
}- Marked with
@Component→ Automatically discovered by Spring Boot. @Order(1)→ Ensures the runner runs first if multiple runners exist.- The
run()method executes logic like sending emails after startup.
package com.training.springboot.runners;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(3)
@Component
public class PushNotification implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
for (String arg : args) {
System.out.println(arg);
}
System.out.println("Sending push notification to manager team...");
System.out.println("Push notification sent!");
}
}- Uses
@Order(3)→ This runner executes after Email and TextMessage runners. - Demonstrates how multiple runners can run in sequence.
ApplicationRunner is another interface used for post-startup logic, but it provides arguments as an ApplicationArguments object:
void run(ApplicationArguments args) throws Exception;- Gives structured access to option and non-option arguments.
package com.training.springboot.runners;
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(2)
@Component
public class TextMessageNotification implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> values = args.getNonOptionArgs();
for (String value : values) {
System.out.println(value);
}
System.out.println("Sending Text Message to Management...");
}
}ApplicationArgumentsgives more control than simpleString... args.- Helps when parsing arguments passed during application startup.
package com.training.springboot.beans;
import org.springframework.stereotype.Component;
@Component
public class Product {
public Product() {
System.out.println("Product is created");
}
}- A simple bean loaded at startup.
- Shows that beans are available when runners execute.
When you start the Spring Boot app:
main()executes → callsSpringApplication.run().- Spring Boot loads the ApplicationContext.
- All
@Componentbeans are created. - Runners (
CommandLineRunner/ApplicationRunner) execute immediately after startup. - The application becomes ready to process further requests.
When you have multiple runners, you can control execution order using:
@Order(1) // Executes first
@Order(2) // Executes second
@Order(3) // Executes thirdLower order number = higher priority.
| Feature | CommandLineRunner | ApplicationRunner |
|---|---|---|
| Input Type | String... args | ApplicationArguments |
| Purpose | Simple argument handling | Structured argument handling |
| Common Use | Logging, emails, basic setup | Config initialization, complex argument parsing |
| Interface Method | run(String... args) |
run(ApplicationArguments args) |
- Load default data into database after app start.
- Validate environment configuration.
- Send startup notification (email/SMS).
- Preload caches or configuration files.
- Runners = Post-startup executors.
- Use them for one-time startup logic.
@Orderdefines execution sequence.CommandLineRunnerfor simple args,ApplicationRunnerfor structured args.
These concepts are essential for backend developers who want to manage initialization logic effectively in Spring Boot applications.
This Markdown file covers multiple Spring Boot concepts — from bean lifecycle to database table creation and data operations using JdbcTemplate — explained step-by-step for complete beginners to intermediate learners.
In this section, we will learn how to create database tables and perform CRUD operations (Create, Read, Update, Delete) using Spring Boot’s JdbcTemplate.
JdbcTemplate is a Spring class that simplifies database interaction. Instead of writing long JDBC boilerplate code (like connection handling, statements, and result sets), we can perform database operations with just a few lines.
JdbcTemplate is automatically configured by Spring Boot when you have the following dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>Your application.properties should include database connection details:
spring.datasource.url=jdbc:mysql://localhost:3306/your_database
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.DriverWhen you want to create a table automatically at startup, you can use CommandLineRunner. The logic inside run() executes right after the application context starts.
package com.training.springboot.tablecreation;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
class TableCreator implements CommandLineRunner {
private final JdbcTemplate jdbcTemplate;
public TableCreator(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void run(String... args) throws Exception {
String sql = "CREATE TABLE IF NOT EXISTS employee (" +
"id INT AUTO_INCREMENT PRIMARY KEY," +
"name VARCHAR(50) NOT NULL," +
"email VARCHAR(50) NOT NULL UNIQUE," +
"password VARCHAR(50) NOT NULL," +
"mobileNo BIGINT," +
"gender CHAR(1)," +
"isMarried BOOLEAN," +
"workingHour FLOAT," +
"salary DOUBLE," +
"dob DATE," +
"joinedAt DATETIME" +
")";
jdbcTemplate.execute(sql);
System.out.println("Employee table created successfully!");
}
}@Component: Marks this class as a Spring-managed bean.CommandLineRunner: Runs code after the application context starts.JdbcTemplate.execute(sql): Executes raw SQL commands.CREATE TABLE IF NOT EXISTS: Ensures table is created only if it doesn’t already exist.
Employee table created successfully!
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.training.springboot.impl.DatabaseOperations;
import com.training.springboot.impl.ProductManagement;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
ProductManagement management = context.getBean("productManagement", ProductManagement.class);
management.loadAllProducts();
}
}This is the entry point of the Spring Boot application. It loads the Spring Context, auto-configures beans, and executes runners.
SpringApplication.run()starts the Spring Boot application.ConfigurableApplicationContextallows you to access Spring beans programmatically.- Beans like
ProductManagementorDatabaseOperationsare auto-created because of the@Componentannotation.
package com.training.springboot.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class DatabaseOperations {
@Autowired
JdbcTemplate jdbcTemplate;
public void addProduct() {
jdbcTemplate.update("INSERT INTO product VALUES(105,'iphone16',80000)");
System.out.println("Product added successfully!");
}
public void deleteProduct() {
jdbcTemplate.update("DELETE FROM product WHERE pid=102");
System.out.println("Product deleted successfully!");
}
}jdbcTemplate.update()is used for INSERT, UPDATE, or DELETE operations.- The SQL query is directly passed inside the
update()method.
package com.training.springboot.impl;
public class ProductDetails {
private int pid;
private String pname;
private double price;
// Getters and Setters
public int getPid() { return pid; }
public void setPid(int pid) { this.pid = pid; }
public String getPname() { return pname; }
public void setPname(String pname) { this.pname = pname; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
}This is a POJO (Plain Old Java Object) used to map data from database rows into Java objects.
package com.training.springboot.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class ProductManagement {
@Autowired
JdbcTemplate jdbcTemplate;
public void saveProducts() {
String query = "INSERT INTO product VALUES(?,?,?)";
jdbcTemplate.update(query, 1111, "Samsung", 100000);
System.out.println("Product saved successfully!");
}
public void loadAllProducts() {
String query = "SELECT * FROM product";
List<ProductDetails> list = jdbcTemplate.query(query, new BeanPropertyRowMapper<>(ProductDetails.class));
list.forEach(product -> {
System.out.println(product.getPid());
System.out.println(product.getPname());
System.out.println(product.getPrice());
});
}
}jdbcTemplate.query()is used for SELECT statements.BeanPropertyRowMapperautomatically maps table columns to Java object fields based on name matching.- Data is printed for all retrieved rows.
101
MacBook Air
150000.0
105
iPhone 16
80000.0
| Concept | Description |
|---|---|
JdbcTemplate |
Simplifies JDBC operations like querying and updates. |
CommandLineRunner |
Runs custom logic after application startup. |
BeanPropertyRowMapper |
Maps table columns to Java object fields. |
@Autowired |
Automatically injects the required bean (like JdbcTemplate). |
@Component |
Marks the class as a Spring-managed bean. |
- Spring Boot automatically configures a DataSource if it finds the necessary dependencies.
- You can use
ApplicationRunnerfor more control over argument parsing. JdbcTemplatehelps prevent SQL injection when used with parameterized queries.- For large applications, move SQL queries to a separate Repository Layer.
✅ Now you’ve learned:
- How to auto-create tables at startup.
- How to perform CRUD operations using JdbcTemplate.
- How to use POJOs and Bean Mappers for structured data handling.
This explanation ensures any beginner can understand the complete flow of database handling in Spring Boot.
This guide includes three complete examples showing how to use Spring Boot + Spring Data JPA for CRUD operations.
com.training.springboot
├── Application.java
├── entity
│ ├── ProductDetails.java
│ └── UserInformations.java
├── repositary
│ ├── ProductDetailsRepositary.java
│ └── UserDetailsRepo.java
└── operations
├── DatabaseOperations.java
└── DatabaseOperationTwo.java
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.training.springboot.operations.DatabaseOperationTwo;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
DatabaseOperationTwo databaseOperationTwo = context.getBean("databaseOperationTwo", DatabaseOperationTwo.class);
databaseOperationTwo.loadAllProducts();
}
}package com.training.springboot.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="product")
public class ProductDetails {
@Id
@Column(name="pid")
private int productId;
@Column(name="pname")
private String productName;
@Column(name="price")
private double productPrice;
public ProductDetails() {}
public ProductDetails(int productId, String productName, double productPrice) {
this.productId = productId;
this.productName = productName;
this.productPrice = productPrice;
}
// getters and setters
}package com.training.springboot.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="USER_INFORMATION")
public class UserInformations {
@Id
@Column(name="user_id")
private long userId;
private String name;
private String contact;
// getters, setters, and toString()
}package com.training.springboot.repositary;
import org.springframework.data.jpa.repository.JpaRepository;
import com.training.springboot.entity.ProductDetails;
public interface ProductDetailsRepositary extends JpaRepository<ProductDetails, Integer> { }package com.training.springboot.repositary;
import org.springframework.data.repository.CrudRepository;
import com.training.springboot.entity.UserInformations;
public interface UserDetailsRepo extends CrudRepository<UserInformations, Long> { }package com.training.springboot.operations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.training.springboot.entity.ProductDetails;
import com.training.springboot.entity.UserInformations;
import com.training.springboot.repositary.ProductDetailsRepositary;
import com.training.springboot.repositary.UserDetailsRepo;
@Component
public class DatabaseOperations {
@Autowired
ProductDetailsRepositary productDetailsRepositary;
@Autowired
UserDetailsRepo userDetailsRepo;
public void addProductInformation() {
ProductDetails p1 = new ProductDetails(111, "Samsung", 120000.99);
productDetailsRepositary.save(p1);
}
public void addUserInformation() {
UserInformations user = new UserInformations();
user.setUserId(1111);
user.setName("Raushan");
user.setContact("+91 6206481133");
userDetailsRepo.save(user);
}
}package com.training.springboot.operations;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.training.springboot.entity.ProductDetails;
import com.training.springboot.repositary.ProductDetailsRepositary;
@Component
public class DatabaseOperationTwo {
@Autowired
ProductDetailsRepositary productDetailsRepositary;
public void addMoreProducts() {
List<ProductDetails> allproducts = new ArrayList<>();
allproducts.add(new ProductDetails(222,"Mouse",50000));
allproducts.add(new ProductDetails(223,"Keyboard",50000));
allproducts.add(new ProductDetails(224,"Disk",50000));
allproducts.add(new ProductDetails(225,"Speaker",50000));
productDetailsRepositary.saveAll(allproducts);
}
public void loadAllProducts() {
List<ProductDetails> list = productDetailsRepositary.findAll();
list.forEach(System.out::println);
}
}com.training.springboot
├── Application.java
├── OrderOperations.java
├── entity/OrderInformation.java
└── repositary/OrderInformationRepositary.java
package com.training.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
OrderOperations operations = context.getBean(OrderOperations.class);
operations.addOrder();
operations.loadAllOrder();
}
}package com.training.springboot;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.training.springboot.entity.OrderInformation;
import com.training.springboot.repositary.OrderInformationRepositary;
@Component
public class OrderOperations {
@Autowired
public OrderInformationRepositary orderRepositary;
public void addOrder() {
OrderInformation order = new OrderInformation(
1, "raushan786267@gmail.com", 3, "Raushan Singh", "6206481133",
"Buxar", 802111, 500000);
orderRepositary.save(order);
}
public void loadAllOrder() {
List<OrderInformation> list = orderRepositary.findAll();
list.forEach(System.out::println);
}
}package com.training.springboot.entity;
import jakarta.persistence.*;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="order_info")
public class OrderInformation {
@Id
@Column(name="order_id")
private long orderId;
@Column(name="email_id")
private String emailId;
private int noOfItems;
private String name;
private String contact;
private String city;
private int pincode;
private double amount;
}package com.training.springboot.repositary;
import org.springframework.data.jpa.repository.JpaRepository;
import com.training.springboot.entity.OrderInformation;
public interface OrderInformationRepositary extends JpaRepository<OrderInformation, Long> { }✅ JPA Configuration (application.properties)
spring.datasource.url=jdbc:mysql://localhost:3306/springdb
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true📚 Notes
ddl-auto=create→ creates tables each runddl-auto=update→ keeps data, updates schemaddl-auto=create-drop→ drops after exitddl-auto=validate→ validates schemaddl-auto=none→ disables schema management
ProductDetails [productId=222, productName=Mouse, productPrice=50000.0]
ProductDetails [productId=223, productName=Keyboard, productPrice=50000.0]
OrderInformation [orderId=1, name=Raushan Singh, amount=500000.0]
This Markdown document shows how to:
- Create entities with JPA annotations
- Use
JpaRepositoryandCrudRepository - Perform basic CRUD operations
- Configure Hibernate via
application.properties
--