Spring自动连接...将源类传递给自动装配的类

时间:2014-09-08 05:08:49

标签: spring log4j

以一种奇怪的要求抓住了。我需要将唯一的错误ID附加到log4j消息并将该消息ID返回给interface.So,我可以创建一个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;
       }
    }

2 个答案:

答案 0 :(得分:3)

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

创建此注释..

/**
* 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...");
 }
}

答案 1 :(得分:1)

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