Home Blog Page 91

Using CommandLineRunner and ApplicationRunner in Spring Boot

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction
  2. What are CommandLineRunner and ApplicationRunner?
  3. Differences Between the Two
  4. When to Use Them
  5. Implementing CommandLineRunner
  6. Implementing ApplicationRunner
  7. Use Cases
  8. Accessing Command-Line Arguments
  9. Best Practices
  10. Conclusion

1. Introduction

In Spring Boot, CommandLineRunner and ApplicationRunner are two special interfaces provided to execute code after the Spring application has fully started and the Spring context is initialized. They’re commonly used for tasks like bootstrapping data, logging startup details, or performing any post-initialization operations.


2. What are CommandLineRunner and ApplicationRunner?

Both CommandLineRunner and ApplicationRunner are callback interfaces used to run code at startup. They are executed after the application context is loaded and right before the application becomes fully available.

  • CommandLineRunner – provides access to raw String[] arguments.
  • ApplicationRunner – provides access to ApplicationArguments (parsed arguments).

3. Differences Between the Two

FeatureCommandLineRunnerApplicationRunner
Argument TypeString[] argsApplicationArguments object
Argument ParsingManualAutomatically parsed
UsageSimple argumentsComplex or optional args

4. When to Use Them

  • Use CommandLineRunner when you just need to access raw arguments directly.
  • Use ApplicationRunner when you want to leverage Spring’s parsing capabilities, such as checking for optional or named parameters.

5. Implementing CommandLineRunner

You can create a bean that implements CommandLineRunner:

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("Application started with CommandLineRunner");
for (String arg : args) {
System.out.println("Arg: " + arg);
}
}
}

Output Example:

java -jar app.jar --spring.profiles.active=dev --customArg=test

This will print each argument in the console.


6. Implementing ApplicationRunner

Here’s how you use ApplicationRunner:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Application started with ApplicationRunner");

if (args.containsOption("customArg")) {
System.out.println("customArg value: " + args.getOptionValues("customArg"));
}

for (String nonOptionArg : args.getNonOptionArgs()) {
System.out.println("Non-option argument: " + nonOptionArg);
}
}
}

This approach is helpful when you want to handle key-value arguments with more granularity.


7. Use Cases

  • Initializing sample data into the database
  • Setting up caches
  • Printing application startup information
  • Triggering some API calls after the application is ready
  • Loading configuration or secrets from external sources

8. Accessing Command-Line Arguments

You can access arguments passed to the application in both cases:

java -jar myapp.jar arg1 --custom=value

In CommandLineRunner, args will contain both arg1 and --custom=value.

In ApplicationRunner, args.getOptionNames() will include "custom", and you can retrieve the value using args.getOptionValues("custom").


9. Best Practices

  • Use @Order or implement Ordered interface if multiple runners are present and order matters.
  • Avoid using runners for application logic that should be part of regular services.
  • Runners are best suited for dev/test setup, logging, or conditional bootstrapping.
  • Wrap critical logic with proper error handling to avoid startup failures.

10. Conclusion

CommandLineRunner and ApplicationRunner provide a clean and simple way to execute code at startup in Spring Boot applications. Choosing the right one depends on the type of arguments and control you need. Understanding and using them effectively can help automate bootstrapping processes, verify configurations, or trigger initial business logic right after the application starts.

Spring Boot DevTools & Live Reload

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction
  2. What is Spring Boot DevTools?
  3. Key Features of DevTools
  4. Setting Up Spring Boot DevTools
  5. Live Reload Explained
  6. Using Live Reload with a Browser
  7. Auto-Restart vs. Live Reload
  8. Customizing DevTools Behavior
  9. Use Cases and Benefits
  10. Common Issues and Troubleshooting
  11. Conclusion

1. Introduction

Spring Boot DevTools is a powerful module that enhances the development experience by offering productivity-boosting features such as automatic restarts, live reloads, and advanced debugging support. These features eliminate the need to manually restart the application after every change, significantly speeding up the development workflow.


2. What is Spring Boot DevTools?

Spring Boot DevTools is a development-time only dependency that helps developers build applications more efficiently. It is not intended to be included in production builds and should only be used during development.

Its primary features include:

  • Automatic application restart when files on the classpath change
  • Live reload integration with the browser
  • Property defaults for development
  • Fast restart using classloader separation

3. Key Features of DevTools

  • Automatic Restart: Monitors classpath files and restarts the application upon changes.
  • Live Reload: Automatically refreshes the browser when HTML/CSS/JS content changes.
  • Disabling Caching: Disables template and static resource caching during development.
  • Remote Debugging: Enables secure remote development sessions.
  • Global Settings: Allows shared DevTools configurations across projects.

4. Setting Up Spring Boot DevTools

Add the DevTools dependency to your project. If you’re using Maven:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>

For Gradle:

developmentOnly 'org.springframework.boot:spring-boot-devtools'
Note: Marking it as developmentOnly or runtime ensures it's not packaged in the production artifact.

5. Live Reload Explained

Live Reload allows you to automatically refresh the browser window whenever changes are made to static resources like HTML, CSS, or JavaScript.

DevTools embeds a LiveReload server on port 35729. When changes are detected, the server notifies connected browsers to refresh.


6. Using Live Reload with a Browser

To enable Live Reload:

  1. Install a LiveReload browser extension (available for Chrome, Firefox).
  2. Enable the extension and start your Spring Boot application.
  3. Make changes to any static file like .html, .css, or .js.
  4. Your browser should refresh automatically.

Alternatively, use Spring Boot + Thymeleaf or any other templating engine to see template updates in real time.


7. Auto-Restart vs. Live Reload

  • Auto-Restart: Triggers when a .class file changes. Spring Boot restarts the application using a separate classloader for speed.
  • Live Reload: Triggers when static resources (e.g., .html, .css) change. Reloads the web page in the browser but doesn’t restart the backend.

Both features are complementary.


8. Customizing DevTools Behavior

You can disable or fine-tune features using application.properties or application.yml:

# Disable restart
spring.devtools.restart.enabled=false

# Enable LiveReload
spring.devtools.livereload.enabled=true

# Change trigger file paths
spring.devtools.restart.additional-paths=src/main/java,src/main/resources

Spring Boot monitors src/main/java and src/main/resources by default, but you can add more paths if needed.


9. Use Cases and Benefits

  • Web developers: See UI changes without reloading manually.
  • Backend developers: Quickly test updated logic or configurations.
  • Full-stack developers: Seamless feedback loop for both client and server changes.
  • Educational use: Ideal for coding demonstrations or learning platforms where real-time feedback is important.

10. Common Issues and Troubleshooting

  • LiveReload not working: Ensure the browser extension is installed and not blocked by browser security.
  • App restarts unexpectedly: Check for file watchers on non-code directories.
  • High memory use: Consider turning off automatic restarts if unnecessary.

Check your IDE’s automatic build settings. IntelliJ IDEA and Eclipse both support auto-compiling changes that trigger restarts.


11. Conclusion

Spring Boot DevTools significantly enhances developer productivity by removing repetitive tasks like restarting the server or refreshing the browser. By leveraging automatic restarts and live reload, you can focus more on development and less on setup or environment concerns. It’s a must-have tool for Spring Boot developers aiming for speed and efficiency in the development cycle.

Profiles and Environment Setup in Spring Boot

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Spring Profiles
  2. Why Use Profiles?
  3. Defining Profiles
  4. Activating Profiles
  5. Profile-Specific Configuration Files
  6. Programmatic Profile Activation
  7. Conditional Beans with @Profile
  8. Default Profiles
  9. Multi-Profile Configurations
  10. Best Practices
  11. Conclusion

1. Introduction to Spring Profiles

Spring Boot supports a powerful feature called profiles, which allows you to define sets of configuration that can be selectively activated depending on the environment—such as development, testing, or production. Profiles make it easy to switch between different application behaviors and settings without modifying your source code.


2. Why Use Profiles?

In a real-world application, you might need:

  • Different databases for dev, test, and prod
  • Logging settings that vary by environment
  • Bean configurations specific to environments
  • Separate APIs or third-party integrations

Spring Profiles help manage these seamlessly by loading only relevant configurations for the currently active profile.


3. Defining Profiles

To define a profile-specific configuration file, you follow a naming pattern:

  • application-dev.properties or application-dev.yml
  • application-prod.properties or application-prod.yml
  • application-test.properties or application-test.yml

These will override the base application.properties or application.yml values when the respective profile is active.


4. Activating Profiles

You can activate a profile in various ways:

A. In application.properties:

spring.profiles.active=dev

B. As command-line argument:

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

C. As environment variable:

SPRING_PROFILES_ACTIVE=prod

D. In programmatic context:

SpringApplication app = new SpringApplication(MyApplication.class);
app.setAdditionalProfiles("test");
app.run(args);

5. Profile-Specific Configuration Files

Suppose you have the following:

application.yml:

server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:default

application-dev.yml:

server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/devdb

When dev is active, the application will override the base config with values from application-dev.yml.


6. Programmatic Profile Activation

In some advanced use cases (like deciding profiles based on a condition), you can activate profiles in code:

public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApp.class);
app.setAdditionalProfiles("dev");
app.run(args);
}

This is useful when external factors decide the environment at runtime.


7. Conditional Beans with @Profile

You can conditionally load beans for specific environments using @Profile.

@Configuration
@Profile("dev")
public class DevDataSourceConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource(...);
}
}
@Configuration
@Profile("prod")
public class ProdDataSourceConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource(...);
}
}

Only one of these will be active at a time, based on the current profile.


8. Default Profiles

If no profile is explicitly set, Spring Boot uses the default profile. You can assign beans or configurations to the default profile by not marking them with @Profile or by marking them as:

@Profile("default")

9. Multi-Profile Configurations

You can activate multiple profiles at once:

java -jar app.jar --spring.profiles.active=dev,cloud

Spring will merge properties from application-dev.properties and application-cloud.properties, with latter keys overriding earlier ones if duplicated.


10. Best Practices

  • Keep shared configuration in application.yml or application.properties
  • Use separate profile-specific files for changing configurations like database URLs or ports
  • Use @Profile to manage bean lifecycles per environment
  • Never hard-code profile names in your core application logic
  • Use environment variables or system properties in production deployment pipelines

11. Conclusion

Spring Boot Profiles provide a clean and powerful way to handle multiple environments. By externalizing configuration and using profile-specific settings, your application becomes flexible, maintainable, and ready for deployment across varied infrastructure.

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.