Spring autowired…pass source class to autowired cl

2019-02-18 23:57发布

Caught up in a weird requirement. I need to attach unique error id to log4j message and return that message id back to interface.So, I though lets create a spring service, like this

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;
   }

  }

and autowired this to wherever i need it.

 public class LoginLogoutController {

    @Autowired
    LoggingService logger;

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

Although it worked fine, but the source class in logger msg is LoggingService which is obvious. What i want is to pass the class in which LoggingService is autowired so that the logger message shows the original source of problem. I tried somehow to change the service but got no further idea how to pass source class

 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
2条回答
劳资没心,怎么记你
2楼-- · 2019-02-19 00:32

I used this mechanism to inject a logger.

Create this annotation..

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

Now lets define a class that actually does the job of injecting the logger implementation.

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

Using it is even simpler. Just add the Logger annotation created above to the Log field in the required class.

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...");
 }
}
查看更多
成全新的幸福
3楼-- · 2019-02-19 00:50

Why dont you use Spring AOP. AOP provides you much accessibility and features, and you can exploit its interesting features later also, when your application becomes heavy. Spring AOP

查看更多
登录 后发表回答