DEV Community

Minsun
Minsun

Posted on

@Slf4j = Facade Pattern + Service Locator Pattern

For months, I initialized loggers at class level:
Logger logger = Logger.getLogger(CurrentClass.getName());

Then a coworker introduced me to @Slf4j, simplifying logging to just annotations and direct log.info/debug calls.

What is SLF4J?

Simple Logging Facade for Java implements the Facade pattern - providing a unified interface to complex subsystems, like a building's facade concealing internal complexity.

Example usage:

@Slf4j
public class MyService {
    public void doSomething() {
        log.info("Hello, SLF4J!");
    }
}
Enter fullscreen mode Exit fullscreen mode

Why SLF4J?

Multiple logging options exist:

1.Log4j:

import org.apache.log4j.Logger;
private static final Logger logger = Logger.getLogger(MyClass.class);
Enter fullscreen mode Exit fullscreen mode

2.java.util.logging:

import java.util.logging.Logger;
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
Enter fullscreen mode Exit fullscreen mode

3.Logback:

import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = (Logger) LoggerFactory.getLogger(MyClass.class);
Enter fullscreen mode Exit fullscreen mode

SLF4J requires only dependency changes, not code modifications, reducing coupling between application and logging implementations.

How SLF4J Works

SLF4J scans classpath for StaticLoggerBinder:

private static void bind() {
    try {
        Class.forName("org.slf4j.impl.StaticLoggerBinder");
    } catch (ClassNotFoundException e) {
        throw new NoClassDefFoundError("No logging implementation found");
    }
}
Enter fullscreen mode Exit fullscreen mode

Binds implementation:

public class StaticLoggerBinder implements LoggerFactoryBinder {
    private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
    private LoggerFactory loggerFactory;

    private StaticLoggerBinder() {
        loggerFactory = new LogbackLoggerFactory();
    }
}
Enter fullscreen mode Exit fullscreen mode

Service Locator Pattern Connection

While studying IoC alternatives to DI, I noticed similarities with the Service Locator pattern:

// Service Locator
public class ServiceLocator {
    private static Map<String, Service> services = new HashMap<>();
    public static Service getService(String name) {
        return services.get(name);
    }
}

// SLF4J's Similar Approach
public class LoggerFactory {
    public static Logger getLogger(Class<?> clazz) {
        return findPlatformLoggerBinder().getLogger(clazz);
    }
}
Enter fullscreen mode Exit fullscreen mode

SLF4J combines both patterns:

  • Facade: Simplifies logging interface
  • Service Locator: Dynamically binds implementations

This dual-pattern approach enables flexible runtime binding while maintaining clean interfaces.

Top comments (0)