Spring Autowiring ...将源类传递给 Autowiring 类

unruledboy 阅读:142 2025-02-15 21:57:57 评论:0

遇到了一个奇怪的要求。我需要将唯一的错误 ID 附加到 log4j 消息并将该消息 ID 返回给接口(interface)。所以,我虽然让我们创建一个 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,这是显而易见的。我想要的是传递 Autowiring 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; 
       } 
    } 

请您参考如下方法:

我使用这种机制来注入(inject)记录器。

创建这个注解..

/** 
* 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 { 
} 

现在让我们定义一个类,它实际上执行注入(inject)记录器实现的工作。

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


标签:Spring
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号