SLF4J Auto Injection of a Logger into beans
Overview
This example shows how to auto-inject a org.slf4j.Logger into any bean that has a method setLogger accepting a logger using a
BeanPostProcessor. This can be customized for any application. I was in need of auto-injecting an already configured logger into all classes, without having the developer having to do the setup of the logger. This way everything is done prior to entering the business logic.
Code Example
package com.voet.rm.util;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.util.ReflectionUtils;
/**
* This class is used to auto-inject a Logger into any bean that has a setLogger
* method that accepts an org.slf4j.Logger class as a parameter.
*
* @author Tim Voet
*/
public class Slf4JBeanPostProcessor implements BeanPostProcessor, Ordered {
final Logger logger = LoggerFactory.getLogger(Slf4JBeanPostProcessor.class);
/**
* This method is used to executed after the initialization
*
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object,
* java.lang.String)
*/
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object,
* java.lang.String)
*/
public Object postProcessBeforeInitialization(final Object bean,
final String beanName) throws BeansException {
logger.debug("Log4J before initialization of '" + beanName + "' bean.");
final Class clazz = bean.getClass();
ReflectionUtils.doWithMethods(clazz,
new ReflectionUtils.MethodCallback() {
public void doWith(Method method) {
if (method.getName().equals("setLogger")) {
try {
PropertyDescriptor pd = BeanUtils
.findPropertyForMethod(method);
// Only set the logger if the types match ( we
// don't want to risk setting a slf4j Logger in
// a log4J class
if (pd.getPropertyType().getCanonicalName()
.equals((Logger.class.getName()))) {
// set the logger
logger.debug("Setting a logger on bean: " + beanName);
pd.getWriteMethod().invoke(
bean,
new Object[] { LoggerFactory
.getLogger(clazz) });
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
}
});
return bean;
}
/*
* (non-Javadoc)
*
* @see org.springframework.core.Ordered#getOrder()
*/
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
--
TimVoet - 20 Feb 2008
Comments