`

自定义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将无法被初始化.

分享到:
评论
1 楼 pan_java 2009-09-29  
学习了.
真是环境育人啊,我们这种小公司想都没有想过这种问题.
希望以后多发表一些这样的文章,谢谢了!

相关推荐

    log4j自定义日志文件名及日志输出格式

    根据项目需要,要求日志文件名及输出的日志内容头为特殊的格式,因此重写了log4j的一些方法,如要求的格式和项目不同,可根据示例参考进行再次的修改

    Log4j-Logger详解

    Log4j-Logger详细说明以及应用

    log4j配置文件

    log4j.rootLogger=info, stdout, log, errorlog log4j.Logger=search,Test ###Console ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j....

    log4j配置及使用

    最新上传的经典的log4j使用文档 Log4j和commons-log4j不是同一个记日志的工具 ①配置根Logger ②配置日志信息输出目的地Appender ③配置日志信息的格式(布局)

    Log4j简介 介绍log4j的原理和用法

    log4j的使用习惯,让每个类都拥有一个private static的Logger对象,用来输出该类中的全部日志信息 ,使用xml文件来完成对log4j环境的配置。在项目的main class中的静态初始化块里放log4j环境的配置代码。注意:在一...

    Apache Log4j_1.2.17 完整依赖包

    Apache Log4j_1.2.17 完整依赖包,在jdk1.8.201中测试通过。使用教程https://www.tutorialspoint.com/springmvc/springmvc_log4j.htm

    log4j日志驱动包

    Log4j比较全面的配置 log4j.rootLogger=DEBUG,CONSOLE,A1,im log4j.addivity.org.apache=true # 应用于控制台 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.Threshold=DEBUG log4j....

    Log4j日志包

    log4j.rootLogger=debug,CONSOLE,testfile,A1,MAIL ################### # Console Appender ################### log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Target=...

    log4j_properties配置详解

    ### set log levels ###log4j.rootLogger = debug , stdout , D , E### 输出到控制台 ###log4j.appender.stdout =org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target =System.outlog4j.appender.stdout....

    log4j.properties

    Log4j配置文件 log4j.properties log4j.rootLogger=DEBUG, Console ,File ,DailyRollingFile ,RollingFile

    log4j-1.2.9

    log4j.rootLogger=DEBUG,A1 设置输出方式,常用的有: ConsoleAppender 在控制器中输出信息 RollingFileApperder 在文件中输出信息,设置此放式后必须设置file名称和路径 dailyRollingFileApperder 以日为单位划分在...

    Log4j 学习笔记.doc

    Log4j 学习笔记. 1. Log4j的类图 2. Logger:日志写出器 1. Logger的输出方法 2. Logger的命名规则 ...5. 我自己的一个使用xml文件配置log4j环境的很简单的例子 6. Log4j的编码习惯 参考资料

    Log4j日志管理系统简单使用说明

     获得了Logger的实例之后,接下来将配置Log4j使用环境:  语法表示:  BasicConfigurator.configure():自动快速地使用缺省Log4j环境。  PropertyConfigurator.configure(String configFilename):读取使用Java...

    logger4j配置文件

    logger4j配置文件

    Java Log4j所需Jar包

    Java Log4j 1,2 所需Jar...用于日志记录的技术很多,如 jdk 的 logger 技术,apache 的 log4j、log4j2 技术等。 Log4j 的全称为 Log for java,即,专门用于 java 语言的日志记录工具。其目前有两个版 本:Log4j 与 Log4j2。

    log4j jar包

    日志类jar包 所属apache分类下 log4j-1.2.17!!! 

    使用log4j进行日志记录

    Log4j提供了灵活的配置方法,默认是调用BasicConfigurator.configure()来进行配置,但如果只是简单的调用BasicConfigurator.configure()来进行配置工作,那么所有的配置都是固定的,不方便以后修改配置。另一种是...

    log4j参考手册

    2.1 Log4J配置 3 2.2 Log4J的类图 4 2.3 日志级别 4 2.4 配置Logger组件 4 2.5 配置Appender组件 5 2.6 配置Layout组件 6 2.7 日志文件的名称 7 2.8 日志文件的大小 7 2.9 Log4j.properties例子 7 3 日志输出方式...

    log4j日志报错解决办法

    提示:log4j:WARN Please initialize the log4j system properly,log4j:WARN No appenders could be found for logger错误的处理办法

    log4j的配置使用

    log4j配置文件,及使用,配置相应包 private static final Logger logger = Logger.getLogger(类名.class.getName()); 在每个类前加该语句,就可以输出相应日志

Global site tag (gtag.js) - Google Analytics