自定义logger注解, 简化log4j的配置

上次在参加支付宝架构培训的时候, 看到他们框架中有一个不错的对logger的注解来简化定义, 具体用法如下:

    @Logger
    private static Log log;

当时觉得不错, 也没问他们怎么实现的, 后来自己做了一个, 基本原理如下:
通过自定义一个BeanPostProcessor, 在对所有bean初始化之前, 对每一个bean的field进行检查, 是否适用了Logger注解, 如果有, 则调用LogFactory创建一个logger实例.

 

做法如下:
1.定义一个Logger注解:

@Retention(RetentionPolicy.RUNTIME)
@Target( {
 ElementType.FIELD
})
public @interface Logger {

}
 

2.创建一个BeanPostProcessor(这个是重点)

public class LogBeanPostProcessor implements BeanPostProcessor {

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

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        List<Class<?>> clazzes = getAllClasses(bean);

        for (Class<?> clazz : clazzes) {
            initializeLog(bean, clazz);
        }

        return bean;
    }

    /**
     * 取得指定bean的class以及所有父类的列表, 该列表排列顺序为从父类到当前类
     * @param bean
     * @return
     */
    private List<Class<?>> getAllClasses(Object bean) {
        Class<? extends Object> clazz = bean.getClass();
        List<Class<?>> clazzes = new ArrayList<Class<?>>();
        while (clazz != null) {
            clazzes.add(clazz);
            clazz = clazz.getSuperclass();
        }

        Collections.reverse(clazzes);
        return clazzes;
    }

    /**
     * 对logger变量进行初始化
     * 
     * @param bean
     * @param clazz
     */
    private void initializeLog(Object bean, Class<? extends Object> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.getAnnotation(Logger.class) == null) {
                continue;
            }

            if (!field.getType().isAssignableFrom(Log.class)) {
                continue;
            }

            field.setAccessible(true);
            try {
                field.set(bean, LogFactory.getLog(clazz));
            } catch (Exception e) {
                throw new BeanInitializationException(String
                        .format("初始化logger失败!bean=%s;field=%s", bean, field));
            }

        }
    }

}

 

3.在spring beans配置文件中加入如下配置:

    <bean id="logBeanPocessor" class="com.mysoft.log.LogBeanPostProcessor" lazy-init="false" />
 

不过这种做法也有一个缺点, 就是这些log的类必须是受spring管理的bean, 否则log将无法被初始化.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值