Spring Extension (1) ― BeanPostProcessor based Logger Injection

2014-11-24 10:33:39 · 作者: · 浏览: 0

场景:
Log Wrapper:slf4j,编码中每个类都需要通过

[java]
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorHandler.class);

private static final Logger LOGGER = LoggerFactory.getLogger(ErrorHandler.class);这种非智能的硬编码方式来生成logger实例.

优化:

在spring框架中,每个类实例化的是由spring ioc完成的.实现BeanPostProcessor接口 能够在实例初始化完成后做一些自定义的逻辑。

spring基于Annotation的初始化类就是实现了BeanPostProcessor接口。例如:@Required && RequiredAnnotationBeanPostProcessor。

故使用如下方式自动化初始Logger实例-基于spring 2.5-3.x:


1、定义Annotation:
[java]
/**
* Log Annotation for Logger Injection
**/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Log {
String value() default "";
}

/**
* Log Annotation for Logger Injection
**/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Log {
String value() default "";
}

2、在目标类定义:

[java]
@Component
public class LoggerDemo{  
@Log  
private Logger logger;  
//some methods  
//some properties
}

@Component
public class LoggerDemo{  
@Log  
private Logger logger;  
//some methods  
//some properties
}

3、自定义BeanPostProcessor


[java]
/**
* init the slf4j logger in each spring bean
*/
@Component
public class LoggerBeanPostProcessor implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(),new FieldCallback() { // spring reflection utils
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);

if (field.getType().equals(Logger.class) && field.isAnnotationPresent(Log.class)) {//Log Annotation check
Log logAnnotation = field.getAnnotation(Log.class);
String loggerName = logAnnotation.value();
Logger logger = null;
if (loggerName != null && !loggerName.equals("")) {
logger = LoggerFactory.getLogger(loggerName);
}else {
logger = LoggerFactory.getLogger(bean.getClass());
}
field.set(bean, logger);// init value
}
}
});
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

}