我现在使用静态方法进行记录(因为我发现登录Android非常容易),但现在我需要为不同的类配置不同的appender,所以我的静态日志记录方法有问题。
我读了Log4J: Strategies for creating Logger instances,我注意到我现在是时候改变日志记录策略了,所以我需要以下代码到我的班级,这需要一个特殊的记录器。
private static final Logger logger = Logger.getLogger(XXXX.class);
我觉得既然这是重复的工作,那么我们有什么方法可以避免向每个类添加重复的代码,或者只是编写更少的代码。 AOP或依赖注入可以做这样的工作吗?
我正在使用log4j和Spring,但是其他任何方法都会受到高度赞赏。
答案 0 :(得分:2)
是的,你可以。
创建自定义注释,如@Logger
@Retention(RUNTIME)//will be used at runtime, so retain till runtime
@Target(FIELD)//field level annotation
public @interface Logger {
}
在由Spring注入的bean中将您的Logger字段注释为@Logger。
@Logger
private Logger logger;
在这里你可以使用slf4j logger,但你可以直接使用log4j等。看看我如何在这里注释logger。这是由Spring创建的bean。
使用名为BeanPostProcessor的Spring生命周期接口,并在方法postProcessBeforeInitialization中使用reflection utils类来注入记录器。
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;
}
}
完成后,让Spring知道您有一个记录器注入器,如:
<bean id="loggerInjector"
class="com.mypackage.LoggerInjector"/>
答案 1 :(得分:1)
您可以尝试使用Lombok项目。你只需要将lombok库添加到你的类路径中,当然你也需要log4j库。并在类级别使用@Slf4j
注释,然后您应该能够像这样编写日志消息。 log.info("message")
而不创建静态记录器实例。
答案 2 :(得分:0)
确实是一个重复的工作&#34;,为每个需要一个的类添加一个记录器 - 但是,请记住,即使使用依赖注入,你仍然需要声明方法变量(&# 34;记录器&#34;,在您的情况下)。所以,它不会为你节省太多打字。
我还建议您使用日志外观(如SLF4J)和底层实现,例如logback。 Logback是由log4j的同一作者编写的,但对these reasons更好。如果您确实选择了这条路线(在您的应用中使用SLF4J),请记住将jcl-over-slf4j添加到您的类路径中(可能在您的pom文件中),因为您正在使用Spring。
再次关于日志记录策略,可能值得查看Logback文档中引用的演示应用程序。示例代码,与您的代码类似,仅使用日志记录外观:
Logger logger = LoggerFactory.getLogger(LoginAction.class);
答案 3 :(得分: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;