【问题标题】:Spring autowired...pass source class to autowired classSpring自动装配...将源类传递给自动装配类
【发布时间】:2014-09-08 05:08:49
【问题描述】:

遇到了一个奇怪的要求。我需要将唯一的错误 ID 附加到 log4j 消息并将该消息 ID 返回到接口。所以,我虽然让我们创建一个 spring 服务,像这样

public class LoggingService {

   protected static Logger logger = LoggerFactory.getLogger(LoggingService.class);



   public String debug(String debug_msg)
   {
       String uniqueMsgId = generateUniqueId();
       logger.debug(concatIdWithMsg(uniqueMsgId, debug_msg));
       return uniqueMsgId;
   }

  }

并将其自动连接到我需要的任何地方。

 public class LoginLogoutController {

    @Autowired
    LoggingService logger;

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String getLoginPage()
    {
       logger.debug("Login page requested");
    }
    }

虽然效果很好,但是 logger msg 中的源类是 LoggingService,这是显而易见的。我想要的是传递自动装配 LoggingService 的类,以便记录器消息显示问题的原始来源。我试图以某种方式改变服务 但不知道如何传递源类

 public class LoggingService<T> {

       protected static Logger logger = null;

       Class<T> sourceClass;

       public void construct(Class<T> sourceClass)
       {
           this.sourceClass = sourceClass;
           logger = LoggerFactory.getLogger(sourceClass);
       }

       public String debug(String debug_msg)
       {
           String uniqueMsgId = generateUniqueId();
           logger.debug(concatIdWithMsg(uniqueMsgId, debug_msg));
           return null;
       }
    }

【问题讨论】:

    标签: spring log4j


    【解决方案1】:

    我使用这种机制注入了一个记录器。

    创建此注释..

    /**
    * Indicates InjectLogger of appropriate type to
    * be supplied at runtime to the annotated field.
    *
    * The injected logger is an appropriate implementation
    * of org.slf4j.Logger.
    */
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    @Retention(RUNTIME)
    @Target(FIELD)
    @Documented
    public @interface InjectLogger {
    }
    

    现在让我们定义一个真正执行注入记录器实现工作的类。

    /**
     * Auto injects the underlying implementation of logger into the bean with field
     * having annotation <code>InjectLogger</code>.
     * 
     */
    import java.lang.reflect.Field;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.util.ReflectionUtils;
    
    import static org.springframework.util.ReflectionUtils.FieldCallback;
    
    public class LoggerInjector implements BeanPostProcessor {
    
     public Object postProcessAfterInitialization(Object bean, String beanName)
       throws BeansException {
      return bean;
     }
    
     public Object postProcessBeforeInitialization(final Object bean,
       String beanName) throws BeansException {
      ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
       public void doWith(Field field) throws IllegalArgumentException,
         IllegalAccessException {
        // make the field accessible if defined private
        ReflectionUtils.makeAccessible(field);
        if (field.getAnnotation(InjectLogger.class) != null) {
         Logger log = LoggerFactory.getLogger(bean.getClass());
         field.set(bean, log);
        }
       }
      });
      return bean;
     }
    }
    

    使用起来更加简单。只需将上面创建的 Logger 注解添加到所需类的 Log 字段中即可。

    import org.slf4j.Logger;
    
    public class Demo {
    
     @InjectLogger
     private Logger log;
    
     public void doSomething() {
      log.info("message");
      log.error("Lets see how the error message looks...");
     }
    }
    

    【讨论】:

    • 但我需要为每条消息或错误生成唯一的消息 ID,并将其与记录器消息一起添加,这就是我创建服务的原因。但是,如果您可以在演示类中简单地声明您的记录器,我不明白为什么需要这样做?
    • 通过这种方式,您可以注入一个您想要的 bean,具有自定义行为,仅带有注释。
    【解决方案2】:

    为什么不使用 Spring AOP。 AOP 为您提供了许多可访问性和功能,当您的应用程序变得繁重时,您也可以在以后利用其有趣的功能。 Spring AOP

    【讨论】:

    • 日志记录是 Spring AOP(面向方面​​编程)的主要用途之一。您可以指定在进入或退出方法时需要记录的内容。 Logging using AOP。也可以查看spring logging
    • @Raju 问题是他需要记录消息并返回日志消息id。我不确定在这种情况下 AOP 将如何帮助他。
    猜你喜欢
    • 1970-01-01
    • 2017-09-07
    • 2015-09-17
    • 2011-01-24
    • 2011-12-31
    • 2012-02-24
    • 2011-07-23
    • 2013-07-23
    • 2017-07-06
    相关资源
    最近更新 更多