`

自定义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  
学习了.
真是环境育人啊,我们这种小公司想都没有想过这种问题.
希望以后多发表一些这样的文章,谢谢了!

相关推荐

    SpringBoot整合log4j

    在Spring Boot应用中,通过`@Autowired`或`@Resource`注解注入`org.apache.logging.log4j.Logger`,然后调用其方法来记录日志。例如: ```java @Autowired private Logger logger; public void someMethod() {...

    hibernate3.3.1接口实现包 slf4j-log4j12-1.5.2

    Log4j12是Log4j的一个较新版本,提供了更高效、更灵活的日志记录,包括自定义布局、过滤器和Appenders,以及支持日志级别(DEBUG、INFO、WARN、ERROR和FATAL)。 **Hibernate与SLF4J-Log4j12集成** 在Hibernate中,...

    纯净版SpringMVC+Ibatis+log4j环境

    5. **配置文件**:log4j.properties或log4j.xml,配置日志的输出行为。 在“springtest”这个项目中,我们可以看到这三个组件是如何整合在一起的。SpringMVC作为应用的控制器,负责接收请求并调用iBatis进行数据...

    【孔浩老师】SpringMVC整合Hibernate(全注解)实现用户管理管理

    \n\n四、Log4j日志处理\n\n1. **配置Log4j**:在项目的类路径下创建log4j.properties或log4j.xml文件,配置日志级别、输出目的地、格式等。例如,设置INFO级别,输出到控制台和日志文件。\n\n2. **日志使用**:在...

    Spring Boot使用EasyExcel导入导出Excel

    EasyExcel则是阿里巴巴开源的一个处理Excel的工具,它简化了Excel操作的复杂性,使得在Spring Boot中实现Excel的导入导出变得非常容易。本文将深入探讨如何在Spring Boot项目中利用EasyExcel进行高效、便捷的数据...

    SpringBoot-AOP-slf4j.Logger:SpringBoot中面向方面的编程,用于创建Java配置。 班级

    Spring Boot默认集成了Logback作为日志系统,SLF4J是其API层,而具体的日志实现可以根据需求更换,例如切换到Log4j2或Java Util Logging。 学习这个主题,你需要掌握以下几个关键点: 1. AOP的基本概念:切面、...

    springboot FeignClient注解及参数

    FeignClient配置类是用于自定义Feign的Encoder、Decoder、LogLevel、Contract等信息的类。在SpringBoot应用程序中,可以通过@Configuration注解来定义FeignClient配置类。 @Configuration public class ...

    Spring 打印机

    Spring本身支持多种日志框架,如Log4j、Logback和Java Util Logging等,这些框架可以通过配置文件(如log4j.properties或logback.xml)进行定制,以满足不同的日志级别(如DEBUG、INFO、WARN、ERROR)和输出格式需求...

    spring-aop-aroud-demo.zip

    - **日志库(Logging Library)**:项目可能已经包含了如Log4j或Logback这样的日志库,用来记录日志信息。环绕通知中会调用这些库的方法,如`logger.info()`或`logger.debug()`,来记录日志。 总结起来,`spring-...

    lombok-1.18.20.zip

    这些注解可以根据指定的日志库(如 Log4j、SLF4J 等)来生成相应的 logger 实例。 7. **@Cleanup**:在 try-catch-finally 块中自动关闭资源,如文件流等。在Java 7及更高版本中,建议使用 try-with-resources 语句...

    SpringBoot面试专题及答案.zip

    1. 日志框架集成:SpringBoot默认使用Logback作为日志系统,也可选择其他如Log4j2。 2. 日志级别:DEBUG、INFO、WARN、ERROR等,可以通过logging.level.&lt;logger-name&gt;配置日志级别。 3. 日志输出位置和格式:可通过...

    lombok.zip

    - `@Log4j`, `@Log4j2`, `@Logback`, `@SLF4J`:自动导入对应日志库的Logger实例,简化日志记录。 5. **其他实用注解**: - `@Value`:与@Data类似,但生成的类是final的,字段也是private且final,适合创建不可...

    lombok-1.18.8lhr.zip

    7. `@Log4j`, `@Slf4j`或`@CommonsLog`: 自动引入日志框架,并生成对应的logger实例。 8. `@Builder`: 为类生成一个构建器(Builder)模式的构造方式,便于创建复杂对象。 9. `@Value`: 生成一个不可变的类,包含...

    hibernate5.2开发导入包

    SLF4J提供了一个抽象层,允许开发者选择不同的日志实现,如Log4j、Logback等。在项目中,需要将SLF4J的API jar包与具体的日志实现jar包一起引入,然后在代码中使用`org.slf4j.Logger`接口进行日志记录。 5. **实体...

    基于SSHI架构的开发平台技术方案

    Log4j是一个流行的日志框架,用于记录应用程序的日志信息。 **1. 日志管理配置** 通过配置文件来定义日志输出的格式、等级和目的地等。 **2. 程序中调用** 在程序中使用`Logger`对象来记录日志信息。 #### 十、...

    Struts2学习文档

    - **实现方式**:给出一个完整的Log4j配置示例。 以上内容详细介绍了Struts2框架的核心组成部分和技术细节,包括Action的实现方式、Result的配置方法、模型驱动的概念、异常处理机制、类型转换的实现、输入校验的...

    spring-boot-starter-logging:日志组件

    如果开发者更倾向于使用Log4j2或JUL,只需将`spring-boot-starter-logging`替换为对应的`spring-boot-starter-log4j2`或`spring-boot-starter-jul`,Spring Boot会自动配置相应的日志系统。 七、日志处理器与监听器...

    spring 基础包(5个)

    虽然Spring提供了自己的`org.springframework.context.support.Logger`接口,但通常推荐使用commons-logging来兼容多种日志实现,如Log4j、Java内置的日志API等。 这五个组件共同构成了Spring框架的基础,使得...

    Java开发系列实用知识库分享

    3. **SpringBoot日志处理**:SpringBoot允许统一的日志处理,通常使用Logback或Log4j2作为默认日志框架。可以使用`@Slf4j`注解配合`Logger`接口进行日志记录,或者自定义全局异常处理器进行日志打印。 4. **Mybatis...

    java问题解决途径

    使用XML配置Log4j - **知识点概述**:Log4j是一款开源的日志框架,它支持定制化的日志输出格式、输出目标(控制台、文件等)及日志级别(DEBUG、INFO、ERROR等)。通过XML配置文件,可以灵活地配置这些选项。 - **...

Global site tag (gtag.js) - Google Analytics