Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有一种简单的方法为每个类创建一个记录器实例?_Java_Spring_Logging_Dependency Injection_Log4j - Fatal编程技术网

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

Java 是否有一种简单的方法为每个类创建一个记录器实例?,java,spring,logging,dependency-injection,log4j,Java,Spring,Logging,Dependency Injection,Log4j,我现在使用静态方法进行日志记录(因为我发现在Android中登录非常容易),但现在我需要为不同的类配置不同的appender,所以静态日志记录方法存在问题 我读到了,我注意到是时候改变日志策略了,所以我需要下面的代码给我的类,它需要一个特殊的日志记录器 private static final Logger logger = Logger.getLogger(XXXX.class); 我觉得既然这是一项重复的工作,那么我们有没有办法避免在每个类中添加重复的代码,或者只编写更少的代码。AOP

我现在使用静态方法进行日志记录(因为我发现在Android中登录非常容易),但现在我需要为不同的类配置不同的appender,所以静态日志记录方法存在问题

我读到了,我注意到是时候改变日志策略了,所以我需要下面的代码给我的类,它需要一个特殊的日志记录器

private static final Logger logger  =  Logger.getLogger(XXXX.class);
我觉得既然这是一项重复的工作,那么我们有没有办法避免在每个类中添加重复的代码,或者只编写更少的代码。AOP或依赖注入能做这样的工作吗

我正在使用log4j和Spring,但是任何其他的方法都将非常感谢

是的,你可以

  • 创建自定义注释,比如@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记录器,但你们可以直接使用log4j等。看看我是如何在这里注释记录器的。这在Spring创建的bean中

  • @Logger
    private Logger logger;
    
  • 使用名为BeanPostProcessor的Spring生命周期接口和方法postProcessBeforeInitialization,使用反射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"/>
    
    
    
向每个需要记录器的类添加记录器确实是一项“重复的工作”——但是,请记住,即使使用依赖项注入,您仍然需要声明方法变量(在您的示例中为“记录器”)。因此,它不会为您节省很多打字时间

我还建议您使用日志facade,比如,以及底层实现,比如logback。Logback是由log4j的同一位作者编写的,但更适合于。如果您确实选择了这个路线(在应用程序中使用SLF4J),请记住将jcl-over-SLF4J添加到您的类路径(可能在pom文件中),因为您使用的是Spring

关于日志策略,可能值得一看Logback文档中引用的演示应用程序。示例代码与您的非常相似,仅使用日志外观:

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

您可以尝试使用Lombok项目。您只需要将lombok库添加到类路径中,当然您也需要log4j库。并在类级别使用
@Slf4j
注释,那么您应该能够像这样编写日志消息
log.info(“message”)
而不创建静态记录器实例


关于这里的更多信息

可以使用工厂方法为您需要的每个记录器在您的上下文中添加记录器bean(尽管这不是通常的方法):

@Autowired
private Logger logger;