SoFunction
Updated on 2025-04-13

Comparison of solutions for static access configuration properties in SpringBoot

Preface

In Spring Boot development, static access to configuration information is a common requirement, especially to directly obtain configuration values ​​in tool classes, constant classes, or non-Bean classes.

Problem background

Suppose our application needs to read the configuration item from it and access the value directly in the tool class, static method, or non-Bean class. Traditional dependency injection methods (such as @Autowired) have the following limitations:

  • Non-Bean classes cannot be directly injected: such as tool classes and static methods cannot obtain configuration classes through @Autowired.
  • Performance overhead of frequently obtaining beans: each time you obtain a bean through () may affect performance.
  • Code coupling: Strong dependence between configuration classes and business logic may reduce code maintainability.

Therefore, we need a solution that requires no dependency injection, statically accessible configuration.

Solution

Solution 1: Bind static variables through Setter method

Core idea: Use Spring's @ConfigurationProperties automatic binding mechanism to assign configuration values ​​directly to static variables through the setter method.

Implementation steps

1. Define the configuration class:

@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
    // Static variables    public static String logotype;

    // Static method    public static String getLogotype() {
        return logotype;
    }

    // Spring injects configuration values ​​through setter    public void setLogotype(String logotype) {
         = logotype; // Directly assign static variables    }
}

Configuration file:

app:
  logotype: "MyLogo"

How to use:

public class Util {
    public static void printLogo() {
        (()); // Directly call static methods    }
}

Principle analysis

Spring's attribute binding mechanism:

  • @ConfigurationProperties What is the function: This annotation scans the properties of the configuration class (field or setter method) and maps the key-value pairs in it to the properties of the bean based on the configuration prefix (such as app).
  • Setter method call: Spring calls the setLogotype method through reflection and passes the configuration value (such as "MyLogo") as a parameter. At this time, the setter method directly assigns the value to the static variable logotype, rather than the instance variable.
  • Sharing of static variables: Since logotype is a class-level static variable, all codes calling () can access the same copy value.

Why it works:

Spring's dependency injection mechanism only focuses on method signatures (such as setLogotype), but not on how parameters are processed within methods. Therefore, even if the setter method directly operates on static variables, Spring will still call the method normally to complete the assignment.

Pros and cons

advantage:

  • Simple and straightforward: No additional tool classes or caches are required, with minimal code volume.
  • Automatic binding: Spring automatically handles the parsing and assignment of configuration files without manual operations.

shortcoming:

  • Destroy encapsulation: Static variables may be modified at will by other code, which poses potential risks.
  • Thread safety issue: If static variables are mutable, thread safety needs to be ensured.
  • Initialization order dependency: You need to ensure that static variables are accessed after Spring container initialization is completed.

Applicable scenarios

  • There are fewer configuration items and need to be implemented quickly.
  • The project is small in scale and does not require high code encapsulation.

Solution 2: Through Environment Tool Class

Core idea: Use Spring's Environment object to directly obtain configuration values ​​and encapsulate access through tool class static methods.

Implementation steps

Create a tool class:

@Component
public class ConfigUtil {
    private static Environment env;

    // Inject Environment via @Autowired    @Autowired
    public void setEnvironment(Environment environment) {
        env = environment;
    }

    // Static method to get configuration value    public static String getLogotype() {
        return ("");
    }
}

How to use:

public class Util {
    public static void printLogo() {
        (());
    }
}

Principle analysis

The role of Environment:

Environment is the core interface of Spring, providing the ability to obtain all configuration information (including, system properties, JVM parameters, etc.).

getProperty method: directly query the configuration value through the key name (such as).

Static caching mechanism:

The tool class injects Environment through @Autowired and caches as static variables. When calling static methods in the subsequent call, the value is directly obtained through () without repeated injection.

Pros and cons

advantage:

  • Flexible extension: You can directly obtain any configuration item through the key name, without modifying the configuration class.
  • Type safety: Supports generic methods such as getProperty("key", Class<T> requiredType) and other methods.

shortcoming:

  • Key name hardcoded: The full key name (such as) of the configuration item needs to be manually maintained, which may introduce typos.
  • Thread-safe dependency: Environment itself is thread-safe, but it is necessary to ensure that the container initialization is completed.

Applicable scenarios

You need to frequently access different configuration items (such as, etc.).

I hope to get the value directly through the key name to avoid over-design of the configuration class.

Solution 3: Obtain Beans through ApplicationContext

Core idea: Use Spring's ApplicationContext static reference to directly obtain the configuration bean and encapsulate access through static methods.

Implementation steps

Save ApplicationContext:

@SpringBootApplication
public class Application {
    public static ConfigurableApplicationContext context;

    public static void main(String[] args) {
        context = (, args);
    }
}

Add static methods to the configuration class:

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

    public String getLogotype() {
        return logotype;
    }

    // Static method to get configuration value    public static String getLogotypeStatic() {
        return ().getLogotype();
    }
}

How to use:

public class Util {
    public static void printLogo() {
        (());
    }
}

Principle analysis

What is ApplicationContext:

ApplicationContext is the core interface of Spring containers that manages the life cycle and dependencies of all beans.

Static reference: When the application starts, save the ApplicationContext as a static variable. In the future, you can directly get the bean through getBean().

Static method encapsulation:

The configuration class provides static methods, obtain its own instance (singleton Bean) through getBean(), and calls the instance method to obtain the configuration value.

Pros and cons

advantage:

  • Flexible access: You can directly access all properties of the configuration class without writing static methods for each field.
  • Compatible with Spring ecosystem: the configuration class is still automatically bound through @ConfigurationProperties without manual processing.

shortcoming:

  • Performance overhead: Every time a static method is called, the bean is retrieved from the container (but Spring's bean is singleton, with minimal actual impact).
  • Dependencies: Make sure that the application has been started and the ApplicationContext has been initialized.

Applicable scenarios

  • There are many configuration items and the configuration class needs to be reused.
  • I hope to maintain the encapsulation of the configuration class and avoid direct exposure of static variables.

Solution comparison and selection suggestions

plan advantage shortcoming Applicable scenarios
Solution 1 (Setter binds static variables) - Simple and straightforward, no extra code required
-Use Spring's automatic binding mechanism
- Possible to destroy encapsulation
- Static variables need to be maintained manually
When there are few configuration items and need to be implemented quickly
Solution 2 (Environment tool class) - Flexible access to any configuration items
- Support type safety
- Need to hardcode the configuration key name When you need to frequently access different configuration items
Solution Three (referenced by ApplicationContext) - Flexible access to all configuration properties
- Compatible with Spring ecosystem
- Get Beans for each call When there are many configuration items and the configuration class needs to be reused

Deep thinking and precautions

1. Thread safety of static variables

Read-only scenario: If static variables are assigned only at initialization (such as Scheme 1), no additional processing is required.

Variable scenario: If you need to dynamically modify the configuration, you need to add a lock or use the volatile keyword:

public class AppConfig {
    private static volatile String logotype; // Use volatile to ensure visibility    // ...
}

2. Initialization order issue

Ensure container initialization is complete: Before static method calls, you must ensure that the Spring application has been started.

Use @PostConstruct: Add an initialization method in the configuration class to ensure that the static variable has been assigned:

@PostConstruct
public void init() {
    ("Config initialized: " + logotype);
}

3. Configuration refresh

Dynamic refresh: If you need hot update configuration, you can combine @RefreshScope or Spring Cloud Config:

@Component
@RefreshScope
public class AppConfig {
    //Configuration class implements dynamic refresh}

Synchronization of static variables: The static variable needs to be reassigned when the configuration is refreshed.

Best Practice Recommendations

Preferential option three:

Getting Beans through ApplicationContext is both flexible and compatible with Spring's configuration management.

Sample code:

public static String getLogotypeStatic() {
    return ().getLogotype();
}

Applicable scenarios for Plan 2:

When frequent access to different configuration items is required, duplicate code can be reduced through the Environment tool class.

Use plan 1 with caution:

Use only when there are few configuration items and high requirements for code simplicity, avoid damaging encapsulation.

Summarize

The essentially a solution for static access configuration is to find a balance between Spring's dependency injection mechanism and the sharing of static variables.

Solution 1: Quick implementation, but attention should be paid to the maintenance of static variables.

Solution 2: Flexible but hard-coded key names are required.

Solution 3: Flexible and compatible with Spring ecosystem, recommended as the first choice.

The above is a detailed comparison of the solution for static access configuration properties in SpringBoot. For more information about SpringBoot static access configuration properties, please follow my other related articles!