有没有一种简单的方法为每个类创建一个记录器实例?

5
我现在正在使用静态方法来记录日志(因为我发现在Android中很容易记录),但是现在我需要为不同的类配置不同的附加器,所以我在使用静态日志记录方法时遇到了问题。
我阅读了Log4J: Strategies for creating Logger instances,我注意到现在是更改日志记录策略的时候了,所以我将需要将以下代码添加到需要特殊记录器的类中。
private static final Logger logger  =  Logger.getLogger(XXXX.class);

我觉得由于这是一个重复的工作,我们是否有办法避免在每个类中添加重复的代码,或者只写更少的代码。AOP或依赖注入可以完成这样的工作吗?

我正在使用log4j和Spring,但如果有其他方法来实现这一点,将不胜感激。

4个回答

3
你可以尝试使用Lombok项目。你只需将lombok库添加到你的类路径中,并且你当然也需要log4j库。在类级别使用@Slf4j注释,然后你应该能够像这样编写日志消息:log.info("message"),而不需要创建静态记录器实例。
更多信息请参考http://projectlombok.org/features/Log.html

2
是的,你可以。
  • Create your customized annotation say @Logger

    @Retention(RUNTIME)//will be used at runtime, so retain till runtime
    @Target(FIELD)//field level annotation
    public @interface Logger {
    }
    
  • Annotate your Logger field as @Logger in the beans which get's injected by Spring.

    @Logger
    private Logger logger;
    

    Here you could use slf4j logger but upto you as you can directly use log4j etc. See how i annotated logger here. This is within the bean which gets created by Spring.

  • Use of Spring lifecycle interface called BeanPostProcessor and in method postProcessBeforeInitialization, using reflection utils class, to inject the logger.

    public class LoggerInjector implements BeanPostProcessor {
    
    /**
     * Return the bean itself.
    */
    public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
        return bean;
    }
    
    /**
     * For all beans before initialization, inject the logger using slf4j.
     * @param bean
     * @param beanName
     * @return returns same bean by injecting logger.
     */
    public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
            public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
                ReflectionUtils.makeAccessible(field);
                if (field.getAnnotation(Logger.class) != null) {
                    if (field.get(bean) == null) {
                        final Logger logger = LoggerFactory.getLogger(bean.getClass());
                        field.set(bean, logger);
                    }
                }
            }
        });
        return bean;
    }
    }
    
  • Once done, let spring know that you have a logger injector like:

    <bean id="loggerInjector" 
        class="com.mypackage.LoggerInjector"/>
    

0

给每个需要日志记录的类添加一个日志记录器确实是一个“重复的工作”--但是请记住,即使使用依赖注入,您仍然需要声明方法变量(在您的情况下为“logger”)。因此,它不会节省您太多打字时间。

我还建议您使用一个日志门面,比如SLF4J,以及一个底层实现,比如logback。Logback是由log4j的同一作者编写的,但出于这些原因,它更好。如果您选择使用SLF4J与您的应用程序,请记得将jcl-over-slf4j添加到您的类路径中(可能在您的pom文件中),因为您正在使用Spring。

再次关于日志记录策略,值得看一下Logback文档中引用的演示应用程序。示例代码与您的代码非常相似,只是使用了日志门面:

Logger logger = LoggerFactory.getLogger(LoginAction.class);

0

可以使用每个所需记录器的factory-method在您的上下文中添加一个记录器bean(尽管这不是通常的方法):

<bean id="logger" scope="prototype" class="org.apache.log4j.Logger" factory-method="getLogger">
    <constructor-arg name="name" value="youLoggerName" />
</bean>

然后你可以简单地注入你的日志记录器:

@Autowired
private Logger logger;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接