4. Logger BeanPostProcessor

There are different logger BeanPostProcessors to dynamically inject a logger based on reflection, interfaces, or annotations. Many loggers are defined with a static reference to the a class for each class and a developer cuts & pastes each logger definition. This can be error prone and the Logger BeanPostProcessors help deal with this problem.

Tim Voet developed this idea and posted the initial code on the site.

Spring Configuration

All of the logger BeanPostProcessors will ignore any logger that isn't defined in the Map of logger factories. The defaults defined are SLF4J, Apache Commons Logging, Log4J, and JDK Logging. A custom list can be set using the loggerFactoryMap property.

Table 1. Default Loggers

LoggerLogger Factory Static Method
org.slf4j.Loggerorg.slf4j.LoggerFactory.getLogger
org.apache.commons.logging.Logorg.apache.commons.logging.LogFactory.getLog
org.apache.log4j.Loggerorg.apache.log4j.Logger.getLogger
java.util.logging.Loggerjava.util.logging.Logger.getLogger

The LoggerBeanPostProcessor uses reflection to set a logger on any method that matches the specified method and the logger being set on it matches the defined loggers and logger factories.

Reflection
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springbyexample.util.log.LoggerBeanPostProcessor">
        <property name="methodName" value="setCustomLogger" />
    </bean>
    
    <bean id="loggerBean" class="org.springbyexample.util.log.LoggerBean" />

</beans>
                    
                

The LoggerAwareBeanPostProcessor only sets subclasses of the LoggerAware interface. The current interfaces are Slf4JLoggerAware, CommonsLoggerAware, Log4JLoggerAware, and JdkLoggerAware.

Interfaces
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springbyexample.util.log.LoggerAwareBeanPostProcessor" />
    
    <bean id="slf4jLoggerBean" class="org.springbyexample.util.log.Slf4JLoggerBean" />
    
    <bean id="commonsLoggerBean" class="org.springbyexample.util.log.CommonsLoggerBean" />
    
    <bean id="log4jLoggerBean" class="org.springbyexample.util.log.Log4JLoggerBean" />
    
    <bean id="jdkLoggerBean" class="org.springbyexample.util.log.JdkLoggerBean" />

</beans>
                    
                

The AnnotationLoggerBeanPostProcessor can be used to inject loggers into fields and methods that have the AutowiredLogger annotation.

Annotations
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springbyexample.util.log.AnnotationLoggerBeanPostProcessor" />
    
    <bean id="loggerBean" class="org.springbyexample.util.log.AnnotationLoggerBean" />

</beans>
                    
                

Code Example

Examples of the beans having loggers inject by the BeanPostProcessors defined in the Spring configurations above.

Example 13. Reflection

                    
public class LoggerBean {

    Logger logger = null;

    /**
     * Gets SLF4J logger.
     */
    public Logger getCustomLogger() {
        return logger;
    }

    /**
     * Sets SLF4J logger.
     */
    public void setCustomLogger(Logger logger) {
        this.logger = logger;
    }
    
}
                    
                

Example 14. Interfaces

                    
public class Slf4JLoggerBean implements Slf4JLoggerAware {

    Logger logger = null;

    /**
     * Gets SLF4J logger.
     */
    public Logger getLogger() {
        return logger;
    }

    /**
     * Sets SLF4J logger.
     */
    public void setLogger(Logger logger) {
        this.logger = logger;
    }
    
}
                    
                

Example 15. Annotations

                    
@AutowiredLogger
final Logger logger = null;
                    
                
                    
@AutowiredLogger
public void setMethodLogger(Logger methodLogger) {
    this.methodLogger = methodLogger;
}