Home

If-else Optimization: Dynamic Bean Loading

Li

Li Wei

September 9, 20254 min read

Title: Optimizing If‑Else with Dynamic Bean Loading

Introduction

When dealing with complex business logic, we often need to execute different processing paths based on various conditions. Traditional if‑else or switch statements can make the code verbose and hard to maintain. This article, based on the ConditionHandler interface from a real project (see reference), explores two strategy‑pattern implementations: Spring’s automatic injection of a Map and dynamic bean loading.

Background

In a routing‑tag condition evaluation system, we must support multiple operators such as greater‑than, less‑than, equal, range, etc. Each operator has its own calculation logic, and the appropriate handler must be selected dynamically according to the operator type.

Core interface design:

Solution 1: Bean Auto‑Wiring

Implementation

Handler implementation example:

How It Works

Assembly process:

  • When the Spring container starts, it scans all classes annotated with @Component.
  • For classes that implement the ConditionHandler interface, Spring instantiates them and registers them as beans.
  • When injecting Map , Spring looks up all beans of type ConditionHandler.
  • It uses the bean name as the key and the bean instance as the value, builds a Map, and injects it.

Pros and Cons

Advantages

  • Concise code; relies on Spring’s automatic injection.
  • No need to maintain a manual registry.
  • Adding a new handler only requires creating a new class and annotating it with @Component.

Disadvantages

  • Tied to the Spring container; cannot be used in non‑Spring environments.
  • Cannot be used in static contexts.
  • Handlers cannot be added or removed at runtime.

Solution 2: Dynamic Bean Loading

Aware Interface System

Spring provides a set of Aware interfaces that let a bean obtain specific framework objects from the Spring container.

Aware is a marker interface indicating that a bean is eligible to be notified by the container via callback methods. Spring offers several Aware interfaces:

  • BeanNameAware – obtain the bean name
  • ApplicationContextAware – obtain the ApplicationContext
  • BeanFactoryAware – obtain the BeanFactory
  • EnvironmentAware – obtain the Environment

BeanNameAware

Interface definition:

How it works:

During a bean’s lifecycle, Spring calls the methods of various Aware interfaces. The invocation timing for BeanNameAware is as follows:

Source code analysis:

In Spring’s AbstractAutowireCapableBeanFactory there is a dedicated method for handling Aware interfaces:

Dynamic Loading Implementation

Enhanced interface design:

Abstract base‑class implementation:

Dynamic registration table design:

Concrete handler implementation:

Loading Process Analysis

Spring container startup phase:

  • Bean instantiation phase:

  • Automatic registration process:

  • Usage phase process:

Dynamic Extension Capability

Add handlers at runtime:

  • Handler management interface:

Thread‑Safety

Since the registry performs bean operations, we must consider concurrent access to the map and potential resource contention:

Comparison of the Two Approaches

Feature Spring Auto‑Wired Map Dynamic Bean Loading
Code volume Less More
Spring dependency Strong Weak
Use in static context Not supported Supported
Dynamic add/remove Not supported Supported
Concurrency handling Spring‑managed Handled manually
Extension Add class + annotation Add class + annotation + registration
Technical complexity Low Medium
Runtime monitoring Difficult Easy

Typical use cases

When to prefer Spring auto‑wired Map:

  • Pure Spring applications
  • Relatively fixed number of handlers
  • No need to use in static contexts
  • Preference for concise code

When to prefer dynamic bean loading:

  • Mixed‑architecture applications
  • Need to operate in non‑Spring environments
  • Need to add or remove handlers at runtime
  • Need to use in static contexts
  • Need runtime monitoring and management

Conclusion

The dynamic bean loading approach leverages Spring’s BeanNameAware mechanism to automatically discover and register handlers. Compared with the simple Spring auto‑wired Map, it offers greater flexibility and extensibility, making it especially suitable for complex business scenarios that require dynamic strategy management.

Key technical points

  • BeanNameAware callback mechanism: enables beans to self‑register
  • Static registry design: supports use outside Spring
  • Thread‑safety guarantees: uses ConcurrentHashMap
  • Dynamic extensibility: add/remove handlers at runtime
  • Robust exception handling: ensures system stability

Whichever solution you choose, both effectively eliminate large amounts of if‑else code, improve maintainability and extensibility, and truly realize the Open/Closed Principle.


Originally written by Li Wei (李唯_) and published in Chinese on 后端技术栈全书 (Full-Stack Backend Engineering). Translated and adapted for DriftSeas with permission.

Keep reading

More related articles from DriftSeas.