Java Omnibus
OOAD & Architecture / J2EE / Jakarta EE Patterns / Service Locator Pattern
J2EE Business Java Order Management
Business

Service Locator Pattern

Service Locator centralizes service lookup and caching, especially in legacy infrastructure-heavy systems where direct dependency injection was difficult or unavailable.

Why This Topic Matters

Why it matters in enterprise Java

Many enterprise Java systems still contain registries, bean factories, or lookup helpers. Understanding the pattern helps you review those systems honestly instead of confusing lookup with dependency injection.

Pattern Essentials

Intent, problem, and solution

Intent

What the pattern is trying to achieve

Provide a centralized access point for locating and optionally caching services or resources.

Problem

What goes wrong without it

Lookup logic is duplicated in many callers, often involving naming services, factories, or infrastructure-specific discovery code.

Solution

How the pattern answers the problem

Move lookup responsibilities into one locator or registry abstraction.

Modern Relevance

Why it still matters now

The pattern is still important mainly as a legacy and infrastructure concept, plus as a comparison point for understanding DI.

Structure

How the collaboration works

  • Client requests a service from the locator.
  • Locator resolves or caches the target service.
  • Service instance is returned to the caller.
  • The client now depends on the locator rather than explicit constructor wiring.
Java Example

Java example in the Order Management domain

Java example: simple registry-style service locator
package org.javaomnibus.ecommerce.business;

import java.util.HashMap;
import java.util.Map;

public final class ServiceLocator {
    private final Map<Class<?>, Object> services = new HashMap<>();

    public <T> void register(Class<T> type, T instance) {
        services.put(type, instance);
    }

    public <T> T resolve(Class<T> type) {
        return type.cast(services.get(type));
    }
}
Code Walkthrough

Step by step

  1. The locator centralizes access to service instances.
  2. Callers no longer need to know how instances are created or found.
  3. The cost is that class dependencies become less visible at construction time.
  4. That is why modern Java teams often prefer DI for application code.
Real-World Usage

Where this pattern shows up

  • Legacy EJB, JNDI, or registry-heavy systems
  • Infrastructure bootstrap layers where explicit injection is impractical
  • Plugin registries with dynamic resolution needs
When Not To Use

Cases where another shape is better

  • Most modern application services and controllers where explicit DI is available
  • Domain code that should keep dependencies obvious and testable
Trade-Offs

Trade-offs and design pressure

  • Service Locator reduces repeated lookup code but hides dependencies from class signatures.
  • It can be pragmatic in legacy or dynamic environments, but it usually weakens readability and unit testing in application code.
Comparison Note

How this differs from nearby patterns

Service Locator centralizes lookup. Dependency Injection makes dependencies explicit. In modern code, that visibility difference usually matters more than the convenience of lookup.

Common Misuse

Mistakes to avoid

  • Calling locator-based code 'dependency injection'
  • Using a locator inside core domain or application services
  • Keeping locators because constructors feel too long instead of fixing the design problem
Related Pages

Related concepts


What To Read Next