Home Blog Page 89

Configuration with application.properties and application.yml in Spring Boot

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Spring Boot Configuration
  2. application.properties vs application.yml
  3. Default Locations and Hierarchy
  4. Common Configuration Examples
  5. Profiles and Environment-Specific Configs
  6. External Configuration Sources
  7. Accessing Configuration in Code
  8. Using @ConfigurationProperties
  9. Validating Configuration Properties
  10. Best Practices
  11. Conclusion

1. Introduction to Spring Boot Configuration

Spring Boot makes it easy to externalize configuration using .properties or .yml files. This allows you to separate environment-specific values (like port numbers, database URLs, logging levels) from your source code, promoting clean code and scalability.


2. application.properties vs application.yml

Both application.properties and application.yml serve the same purpose, with different syntax:

Example – application.properties:

server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

Equivalent in application.yml:

server:
port: 8081

spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password

Use .properties if you prefer flat key-value pairs and .yml if you want hierarchical configuration with better readability.


3. Default Locations and Hierarchy

Spring Boot looks for these files in the following order:

  1. application.properties or application.yml in src/main/resources/
  2. External config via command-line args or environment variables
  3. Config files specified via --spring.config.location
  4. Config files in config/ subdirectory

Priority: Command-line > External file > Internal file


4. Common Configuration Examples

Server:

server.port=8080
server.servlet.context-path=/api

Logging:

logging.level.org.springframework=INFO
logging.level.com.myapp=DEBUG

Database:

spring.datasource.url=jdbc:postgresql://localhost:5432/db
spring.datasource.username=postgres
spring.datasource.password=secret
spring.jpa.hibernate.ddl-auto=update

Thymeleaf (template engine):

spring.thymeleaf.cache=false

5. Profiles and Environment-Specific Configs

Spring Boot allows defining multiple profiles like dev, test, prod.

Structure:

  • application.properties → Default config
  • application-dev.properties → Dev config
  • application-prod.yml → Production config

Activate a profile:

spring.profiles.active=dev

This can also be done via command line:

java -jar app.jar --spring.profiles.active=prod

6. External Configuration Sources

Besides internal files, Spring Boot can read config from:

  • Command-line arguments
  • Environment variables
  • Config data from a .jar
  • OS-level SPRING_APPLICATION_JSON
  • External config servers (e.g., Spring Cloud Config)

This makes it highly flexible for deploying to containers or cloud environments.


7. Accessing Configuration in Code

Use @Value to inject a value:

@Value("${server.port}")
private int serverPort;

Injecting list or map:

app:
servers:
- dev.example.com
- prod.example.com
@Value("${app.servers}")
private List<String> servers;

8. Using @ConfigurationProperties

For grouped config values:

app:
title: My App
features:
enableAuth: true
enablePayment: false

Define POJO:

@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
private String title;
private Features features;

public static class Features {
private boolean enableAuth;
private boolean enablePayment;
}
}

Enable with:

@EnableConfigurationProperties

or annotate the POJO with @ConfigurationProperties.


9. Validating Configuration Properties

Spring Boot supports bean validation with @Validated:

@Component
@ConfigurationProperties(prefix = "app")
@Validated
public class AppConfig {
@NotBlank
private String title;
}

This ensures invalid configs are caught at startup, avoiding runtime errors.


10. Best Practices

  • Use .yml for structured configs, .properties for simpler setups.
  • Always define environment-specific profiles for better manageability.
  • Secure sensitive data using environment variables or secrets managers.
  • Group related properties with @ConfigurationProperties instead of multiple @Value.
  • Use validation to enforce correct configurations.

11. Conclusion

application.properties and application.yml are fundamental to configuring Spring Boot applications. They offer a centralized and flexible way to manage all settings, and understanding their usage is crucial for any Spring developer. As your application scales, these files become the blueprint of environment-specific behavior.

Component Scanning and Bean Lifecycle in Spring Boot

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Component Scanning
  2. Default Component Scanning Behavior
  3. Customizing Component Scanning
  4. Spring Bean Lifecycle Overview
  5. Bean Initialization and Destruction
  6. Bean Lifecycle Hooks: @PostConstruct and @PreDestroy
  7. Using InitializingBean and DisposableBean Interfaces
  8. Using @Bean with initMethod and destroyMethod
  9. Lifecycle Annotations vs Interfaces
  10. Best Practices
  11. Conclusion

1. Introduction to Component Scanning

Spring Boot uses Component Scanning to automatically detect and register beans (classes) into the application context based on annotations. This mechanism reduces boilerplate configuration and allows Spring to manage your classes as beans without explicit XML or Java-based registration.


2. Default Component Scanning Behavior

By default, Spring Boot scans for components (like @Component, @Service, @Repository, and @Controller) in the same package as the main application class and its sub-packages.

Example:

@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}

If MyApp is in the package com.example, Spring will scan com.example and all its sub-packages automatically.


3. Customizing Component Scanning

To scan additional packages or control scanning behavior, use @ComponentScan:

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.services", "com.example.controllers"})
public class MyApp { }

You can also exclude or include components based on annotations or custom filters:

@ComponentScan(
basePackages = "com.example",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Deprecated.class)
)

4. Spring Bean Lifecycle Overview

A Spring Bean is an object managed by the Spring IoC (Inversion of Control) container. The lifecycle of a bean includes:

  • Instantiation
  • Dependency Injection (Population)
  • Custom Initialization
  • Usage
  • Custom Destruction

5. Bean Initialization and Destruction

Spring provides multiple ways to hook into the bean lifecycle:

  • Annotation-based (@PostConstruct, @PreDestroy)
  • Interface-based (InitializingBean, DisposableBean)
  • XML-based (not commonly used in Spring Boot)
  • Java config using @Bean(initMethod, destroyMethod)

6. Bean Lifecycle Hooks: @PostConstruct and @PreDestroy

These annotations are used on methods that should run after dependency injection and before bean destruction:

@Component
public class MyService {

@PostConstruct
public void init() {
System.out.println("Bean is going through init.");
}

@PreDestroy
public void destroy() {
System.out.println("Bean will be destroyed.");
}
}

Requirements:

  • Must be void
  • No parameters
  • Only one method per annotation

7. Using InitializingBean and DisposableBean Interfaces

These are older but still valid ways to handle lifecycle events:

@Component
public class MyService implements InitializingBean, DisposableBean {

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean: afterPropertiesSet called.");
}

@Override
public void destroy() throws Exception {
System.out.println("DisposableBean: destroy called.");
}
}

These are interface-based, which may reduce flexibility compared to annotations.


8. Using @Bean with initMethod and destroyMethod

If you’re using Java-based configuration and defining beans with @Bean, you can specify lifecycle methods directly:

@Configuration
public class AppConfig {

@Bean(initMethod = "init", destroyMethod = "cleanup")
public MyBean myBean() {
return new MyBean();
}
}

Inside MyBean:

public class MyBean {
public void init() {
System.out.println("Init method called.");
}

public void cleanup() {
System.out.println("Destroy method called.");
}
}

9. Lifecycle Annotations vs Interfaces

Feature@PostConstruct/@PreDestroyInitializingBean/DisposableBean
StyleDeclarative (Annotation)Programmatic (Interface)
Preferred in Spring Boot✅ Yes❌ Less preferred
Testable✅ Better⚠️ Coupled to Spring API
Flexibility✅ High⚠️ Low (must implement interfaces)

10. Best Practices

  • Use @PostConstruct and @PreDestroy for cleaner code and better decoupling.
  • Avoid field injection and prefer constructor injection for lifecycle-safe design.
  • Minimize bean lifecycle logic and move business logic into proper service layers.
  • Use @ComponentScan sparingly to avoid unnecessarily loading unwanted components.

11. Conclusion

Understanding Component Scanning and the Bean Lifecycle is essential when working with Spring Boot. These concepts ensure that your application is both modular and maintainable, while taking full advantage of Spring’s powerful dependency injection and lifecycle management capabilities.

Dependency Injection in Spring Boot (Constructor, Field, Setter Injection)

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Dependency Injection
  2. Why Dependency Injection?
  3. Types of Dependency Injection in Spring
    • Constructor Injection
    • Field Injection
    • Setter Injection
  4. Comparing the Three Types
  5. Choosing the Right Approach
  6. Common Pitfalls and Best Practices
  7. Conclusion

1. Introduction to Dependency Injection

Dependency Injection (DI) is a core design pattern used in the Spring Framework to manage object creation and wiring. It allows you to write loosely coupled and more maintainable code by removing the responsibility of managing dependencies from the classes themselves.

Spring Boot leverages this concept extensively using annotations and the Spring container (also called the ApplicationContext) to inject dependencies at runtime.


2. Why Dependency Injection?

Without DI, objects are responsible for instantiating their dependencies. This leads to tightly coupled code, making it difficult to test, extend, or maintain. DI allows us to:

  • Separate configuration from application logic
  • Promote code reusability and testability
  • Simplify code by letting the framework handle wiring

For example, instead of:

Service service = new ServiceImpl();

With DI:

@Autowired
private Service service;

The Spring container injects ServiceImpl automatically.


3. Types of Dependency Injection in Spring

Spring supports three primary types of dependency injection:

3.1 Constructor Injection

Constructor injection is the recommended and most commonly used form. It makes dependencies immutable and helps with unit testing by ensuring all required dependencies are provided.

Example:

@Service
public class UserService {

private final UserRepository userRepository;

@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

public void process() {
userRepository.save(new User());
}
}

If there’s only one constructor, the @Autowired annotation is optional.

3.2 Field Injection

Field injection directly injects dependencies into class fields. It’s concise but not recommended for serious applications due to testability and maintainability concerns.

Example:

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public void process() {
userRepository.save(new User());
}
}

This works but hides the actual dependencies, which may cause problems in larger applications or during testing.

3.3 Setter Injection

Setter injection allows injecting optional dependencies through setter methods. It’s useful when a dependency is not required for object creation but might be needed later.

Example:

@Service
public class UserService {

private UserRepository userRepository;

@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}

public void process() {
userRepository.save(new User());
}
}

Setter injection makes dependencies optional and supports mutable objects.


4. Comparing the Three Types

FeatureConstructor InjectionField InjectionSetter Injection
Immutability✅ Yes❌ No❌ No
Testability✅ High❌ Low⚠️ Medium
Readability✅ Clear✅ Concise⚠️ Verbose
Supports Optional Values⚠️ Needs @Nullable✅ Yes✅ Yes
Required Dependency Check✅ Compile-Time❌ Runtime❌ Runtime

5. Choosing the Right Approach

  • Use constructor injection when possible. It ensures required dependencies are not null and promotes immutability.
  • Avoid field injection in production code unless necessary (e.g., in test classes or configurations).
  • Use setter injection for optional dependencies or when using frameworks that need default constructors (e.g., some serialization libraries).

6. Common Pitfalls and Best Practices

  • Avoid circular dependencies: If two beans depend on each other via constructor injection, Spring will fail to instantiate them.
  • Do not mix all injection types within the same class unless there’s a strong reason.
  • Mark injected fields as final when using constructor injection to guarantee immutability.
  • Use @Qualifier when multiple implementations of an interface are present: @Autowired @Qualifier("specificRepository") private UserRepository userRepository;
  • For optional dependencies, use: public UserService(@Autowired(required = false) UserRepository repo) { ... } or @Autowired public void setRepo(@Nullable UserRepository repo) { ... }

7. Conclusion

Dependency Injection is at the heart of the Spring Boot programming model. Understanding the three forms—constructor, field, and setter injection—allows developers to write clean, testable, and maintainable applications. While all forms are supported, constructor injection is typically preferred due to its clarity and reliability.

@SpringBootApplication and Auto-Configuration in Spring Boot

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to @SpringBootApplication
  2. Understanding What @SpringBootApplication Does
  3. Breakdown of Combined Annotations
  4. What is Auto-Configuration?
  5. How Auto-Configuration Works
  6. Disabling Auto-Configuration
  7. Customizing Auto-Configuration
  8. Common Auto-Configured Components
  9. Best Practices
  10. Conclusion

1. Introduction to @SpringBootApplication

When building a Spring Boot application, one of the first things you’ll encounter is the @SpringBootApplication annotation. It is the backbone of any Spring Boot app and is typically placed on the main class to denote it as the entry point.

Example:

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

This annotation streamlines the configuration process and serves as a powerful entry point for Spring Boot’s capabilities.


2. Understanding What @SpringBootApplication Does

@SpringBootApplication is a meta-annotation, meaning it’s composed of several other annotations that make it a compact yet powerful tool for application configuration.

Under the hood, it includes:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan

Each of these plays a critical role in setting up the application context.


3. Breakdown of Combined Annotations

@Configuration

Indicates that the class can be used by the Spring IoC container as a source of bean definitions.

@EnableAutoConfiguration

Tells Spring Boot to automatically configure your application based on the dependencies on the classpath. This is what enables Spring Boot to auto-configure database connections, web servers, security, etc., without manual setup.

@ComponentScan

Enables component scanning so that classes annotated with @Component, @Service, @Repository, and @Controller are automatically discovered and registered as beans.


4. What is Auto-Configuration?

Auto-configuration is a powerful feature in Spring Boot that automatically sets up your application context based on the libraries available on the classpath.

For example:

  • If Spring MVC is in your classpath, Spring Boot configures a DispatcherServlet.
  • If there’s an embedded database like H2, it will configure a DataSource for you.
  • If Thymeleaf is present, it sets up the view resolver automatically.

You don’t have to define these beans explicitly unless you want to override the default behavior.


5. How Auto-Configuration Works

Spring Boot uses the @EnableAutoConfiguration annotation to load META-INF/spring.factories from the classpath. These factory files point to auto-configuration classes which Spring loads using @Conditional annotations.

Key mechanisms:

  • @ConditionalOnClass: Activates config if a class is present
  • @ConditionalOnMissingBean: Applies config only if no custom bean is defined
  • @ConditionalOnProperty: Configures behavior based on property values

Example:

@ConditionalOnClass(DataSource.class)
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}

6. Disabling Auto-Configuration

Sometimes, auto-configuration may not be desired. You can disable specific configurations using:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

Or use properties to disable certain behaviors in application.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

7. Customizing Auto-Configuration

You can override auto-configured beans simply by defining your own bean with the same type:

@Bean
public DataSource dataSource() {
// custom DataSource setup
}

You can also influence auto-configuration using application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=secret

8. Common Auto-Configured Components

Some of the frequently auto-configured parts include:

  • Embedded Tomcat, Jetty, or Undertow for web applications
  • Spring MVC DispatcherServlet
  • JPA EntityManagerFactory
  • DataSource configuration
  • Spring Security filter chains
  • Logging (Logback, Log4j2) setup
  • Message converters for REST APIs
  • Error handling pages

Each of these has its own auto-configuration class.


9. Best Practices

  • Place @SpringBootApplication on a class in the root package to enable component scanning for the whole project.
  • Let Spring Boot auto-configure as much as possible to reduce boilerplate.
  • Customize only when necessary to avoid configuration conflicts.
  • Avoid disabling auto-configuration unless you have a specific use case.

10. Conclusion

The @SpringBootApplication annotation and Spring Boot’s auto-configuration capabilities dramatically reduce the amount of setup required to start a new Spring project. They provide sensible defaults and intelligent configurations that just work out of the box. Understanding how this mechanism works is essential for tweaking behavior, resolving conflicts, and building scalable and maintainable applications.

Setting Up a Spring Boot Project (Spring Initializr)

0
java spring boot course
java spring boot course

Table of Contents

  1. Overview of Spring Boot Project Setup
  2. What is Spring Initializr?
  3. Generating a Spring Boot Project with Spring Initializr
  4. Project Structure Explained
  5. Importing the Project into an IDE
  6. Running Your First Spring Boot Application
  7. Verifying Setup and Troubleshooting
  8. Conclusion

1. Overview of Spring Boot Project Setup

Setting up a traditional Spring application used to involve multiple steps like configuring XML files, setting up application servers, and managing dependencies manually. Spring Boot eliminates most of this boilerplate by providing a streamlined approach to project setup using Spring Initializr.

With Spring Boot, you can:

  • Start a production-ready application quickly
  • Include only the necessary dependencies
  • Use embedded servers (Tomcat, Jetty)
  • Leverage annotations and Java configuration over XML

2. What is Spring Initializr?

Spring Initializr is a web-based tool (also available as an API and IntelliJ plugin) that allows developers to generate a new Spring Boot project structure with a custom selection of dependencies, Java version, packaging type, and build tool.

You can access it at: https://start.spring.io

Spring Initializr provides:

  • Pre-configured build files (Maven or Gradle)
  • Auto-generated source code structure
  • Starter dependencies
  • Compatible setup with IntelliJ IDEA, Eclipse, VS Code, and other IDEs

3. Generating a Spring Boot Project with Spring Initializr

Follow these steps to generate your first Spring Boot project:

Step 1: Visit Spring Initializr

Go to https://start.spring.io

Step 2: Choose Project Settings

  • Project: Maven or Gradle
  • Language: Java
  • Spring Boot Version: Latest stable version
  • Group: com.example
  • Artifact: demo
  • Name: demo
  • Description: Demo project for Spring Boot
  • Package name: com.example.demo
  • Packaging: Jar (preferred) or War
  • Java version: Choose based on your local setup (e.g., 17 or 21)

Step 3: Add Dependencies

Start typing to search and add dependencies such as:

  • Spring Web (for building REST APIs)
  • Spring Boot DevTools (for hot reload)
  • Spring Data JPA (for database access)
  • MySQL Driver (if you’ll use MySQL)
  • Spring Security, Thymeleaf, etc., as needed

Step 4: Generate and Download the Project

Click “Generate” to download a .zip file of the project.

Step 5: Extract the ZIP

Unzip the file to a desired folder on your local machine.


4. Project Structure Explained

After unzipping and opening the project, you’ll see:

demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ └── DemoApplication.java
│ │ └── resources/
│ │ ├── application.properties
│ │ ├── static/
│ │ └── templates/
│ └── test/
│ └── java/
│ └── com/example/demo/
│ └── DemoApplicationTests.java
├── pom.xml or build.gradle
  • DemoApplication.java: Main class annotated with @SpringBootApplication
  • application.properties: Configuration file
  • static/: For static files (CSS, JS)
  • templates/: For server-side templates like Thymeleaf
  • pom.xml: Maven build file listing dependencies

5. Importing the Project into an IDE

IntelliJ IDEA

  • Open IntelliJ
  • Choose “Open” and select the root folder of the unzipped project
  • IntelliJ will detect the Maven/Gradle project and import dependencies automatically

Eclipse or STS

  • File → Import → Existing Maven/Gradle Project
  • Choose the extracted project folder
  • Wait for the build process to complete

6. Running Your First Spring Boot Application

Once imported, you can run your application:

Using IntelliJ

Right-click on DemoApplication.java → Run

Using Command Line

Navigate to the project folder and run:

./mvnw spring-boot:run

or for Gradle:

./gradlew bootRun

After a successful run, you’ll see output similar to:

Tomcat started on port(s): 8080 (http) with context path ''
Started DemoApplication in 2.345 seconds

Now visit: http://localhost:8080


7. Verifying Setup and Troubleshooting

Verify:

  • Project runs without errors
  • Tomcat starts on port 8080
  • Application context loads successfully

Common Issues:

  • Java version mismatch: Ensure you’re using the correct JDK version.
  • Maven/Gradle not installed: Use the provided wrapper scripts (mvnw or gradlew)
  • IDE not detecting dependencies: Force a Maven/Gradle reimport

8. Conclusion

Setting up a Spring Boot project has never been easier, thanks to Spring Initializr. In just a few clicks, you get a production-ready project structure complete with a modern build tool, embedded server, and dependency management. This setup forms the foundation for developing robust Spring Boot applications rapidly, reducing configuration overhead and improving your development speed.