Spring Boot 2: spring.factories

About

In Spring Boot 2, spring.factories is a special file located under META-INF/ in a jar (or our project’s resources). It’s used to register various Spring Boot infrastructure components, especially for auto-configuration, application context initializers, event listeners, and more.

It is part of the SpringFactoriesLoader mechanism, which loads class names by reading this file.

Where Is It Located?

We must place it under:

src/main/resources/META-INF/spring.factories

This file is included in our built JAR and used by Spring Boot during startup.

Format of the File

It is a key-value pair format using fully qualified class names.

# Format:
<interface or annotation>=<implementation class 1>,<implementation class 2>,...

# Example for auto-configuration:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.MyAutoConfiguration

Each key is a known interface or annotation, and the values are implementations of that key.'

Common Keys Used in spring.factories

Key
Purpose

org.springframework.boot.autoconfigure.EnableAutoConfiguration

Registers auto-configuration classes

org.springframework.context.ApplicationListener

Registers application event listeners

org.springframework.context.ApplicationContextInitializer

Registers context initializers

org.springframework.boot.env.EnvironmentPostProcessor

Modifies the environment before context is created

org.springframework.boot.SpringApplicationRunListener

Hooks into the run lifecycle of SpringApplication

When to Use spring.factories

Use it when:

  • We're creating a reusable Spring Boot library/module

  • We want to plug into Spring Boot's lifecycle without requiring users to manually configure anything

  • We need to provide beans automatically based on conditions (classpath, properties, etc.)

Examples with Spring Boot 2

1. org.springframework.boot.autoconfigure.EnableAutoConfiguration

Use Case

We are building a reusable library that should provide a bean automatically when certain conditions are met (e.g., class exists or a property is set).

Code Example

// File: com.example.autoconfig.MyServiceAutoConfig.java
@Configuration
@ConditionalOnClass(MyService.class) // Only configures if MyService is on the classpath
public class MyServiceAutoConfig {

    @Bean
    public MyService myService() {
        return new MyService("Configured from AutoConfig!");
    }
}
# File: META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyServiceAutoConfig
  • This auto-configuration will automatically register MyService if MyService is present.

  • No need to annotate it with @ComponentScan or @Import manually.

  • Widely used in Spring Boot starters.

2. org.springframework.context.ApplicationListener

Use Case

We want to run some code when specific Spring lifecycle events happen (like app context started, ready, closed, etc.).

Code Example

// File: com.example.listeners.AppReadyLogger.java
public class AppReadyLogger implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println("Application is fully started and ready!");
    }
}
org.springframework.context.ApplicationListener=\
com.example.listeners.AppReadyLogger
  • This runs after the application is fully initialized.

  • No need to register this bean manually—Spring picks it up automatically.

3. org.springframework.context.ApplicationContextInitializer

Use Case

We want to customize or register beans before the Spring context is refreshed.

Code Example

// File: com.example.initializer.MyContextInitializer.java
public class MyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext context) {
        System.out.println("Context is being initialized...");
        // We could register a bean or manipulate the context here
    }
}
org.springframework.context.ApplicationContextInitializer=\
com.example.initializer.MyContextInitializer
  • This runs very early, before any beans are created.

  • Useful to customize context or add profiles or property sources dynamically.

4. org.springframework.boot.env.EnvironmentPostProcessor

Use Case

We want to programmatically add environment variables or property sources before anything loads.

Code Example

// File: com.example.env.AppNameSetter.java
public class AppNameSetter implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        environment.getSystemProperties().putIfAbsent("app.name", "CustomSpringBootApp");
    }
}
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.env.AppNameSetter
  • Runs before the context is created.

  • Use it to dynamically inject properties (from DB, vault, or logic).

5. org.springframework.boot.SpringApplicationRunListener

Use Case

We want to hook into the entire Spring Boot lifecycle — from starting to stopping.

Code Example

// File: com.example.lifecycle.MyRunListener.java
public class MyRunListener implements SpringApplicationRunListener {

    // Mandatory constructor
    public MyRunListener(SpringApplication application, String[] args) {}

    @Override
    public void starting() {
        System.out.println("Spring Boot is starting...");
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("Context started.");
    }
}
org.springframework.boot.SpringApplicationRunListener=\
com.example.lifecycle.MyRunListener
  • Requires a constructor with (SpringApplication, String[])

  • Advanced hook—use sparingly for lifecycle-related logging or metrics

Comparison

Key
When It Runs
Purpose
Common Use

EnableAutoConfiguration

At startup

Auto-register beans

Used in starter libraries

ApplicationListener

On events

React to events

Notify, log, retry logic

ApplicationContextInitializer

Before context refresh

Customize context

Add profiles, log context info

EnvironmentPostProcessor

Before context creation

Inject properties

Read from vault, set defaults

SpringApplicationRunListener

Entire lifecycle

Monitor startup

Telemetry, custom logs

Why and When to use spring.factories instead of @Component or @Configuration ?

When to Use @Component / @Configuration

These are ideal for application code, where:

  • We control the application startup

  • We are writing code inside a Spring Boot project

  • We want Spring to discover the bean via component scanning

Example:

@Component
public class MyService {}

Spring will pick it up if the class is in a package covered by @SpringBootApplication.

When to Use spring.factories

Use it when we're building a library, framework extension, or plugin that needs to auto-register beans or behaviors without the application developer doing anything.

It allows:

  • Automatic registration of beans/configurations across modules or JARs

  • Avoiding the need for @ComponentScan in external modules

  • Providing conditional configuration via @ConditionalOn... annotations

  • Integrating deeply into Spring Boot lifecycle (e.g. env post-processors, listeners)

Example

Imagine we're building a reusable Starter module like my-logging-starter.

If we use @Component

Spring won’t scan it unless the application explicitly scans your package.

If we use spring.factories

It just works when the library is on the classpath. No additional configuration required.

# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.logging.LoggingAutoConfiguration

Now LoggingAutoConfiguration runs automatically.

Last updated

Was this helpful?