java – Spring构建器注入SLF4J记录器 – 如何获取注入目标类?

我正在尝试使用Spring将SLF4J记录器注入类中,如下所示:

@Component
public class Example {

  private final Logger logger;

  @Autowired
  public Example(final Logger logger) {
    this.logger = logger;
  }
}

我找到了我实施的FactoryBean类.但问题是我无法获得有关注射目标的任何信息:

public class LoggingFactoryBean implements FactoryBean<Logger> {

    @Override
    public Class<?> getObjectType() {
        return Logger.class;
    }  

    @Override
    public boolean isSingleton() {  
        return false;
    }

    @Override
    public Logger getObject() throws Exception {
        return LoggerFactory.getLogger(/* how do I get a hold of the target class (Example.class) here? */);
    }
}   

FactoryBean甚至是正确的方式吗?当使用picocontainers factory injection时,您将获得传入的目标类型.在guice中它有点trickier.但是如何在Spring中完成这个?

这是您的解决方案的替代方案.您可以通过BeanFactoryPostProcessor实现实现您的目标.

我们假设你想要一个有记录的类.这里是:

  package log;
  import org.apache.log4j.Logger;

  @Loggable
  public class MyBean {

     private Logger logger;
  }

正如你可以看到,这个类什么也不做,只是为了简单起来成为一个记录器容器.这里唯一显着的是@Loggable注释.
这里它的源代码:

package log;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Loggable {
}

此注释只是进一步处理的标记.这里是一个最有趣的部分:

package log;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import java.lang.reflect.Field;

public class LoggerBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String[] names = beanFactory.getBeanDefinitionNames();
        for(String name : names){
            Object bean = beanFactory.getBean(name);
            if(bean.getClass().isAnnotationPresent(Loggable.class)){
                try {
                    Field field = bean.getClass().getDeclaredField("logger");
                    field.setAccessible(true);
                    field.set(bean, Logger.getLogger(bean.getClass()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

它搜索所有的bean,如果一个bean被标记为@Loggable,它将使用name logger初始化其私有字段.您可以更进一步,并在@Loggable注释中传递一些参数.例如,它可以是对应于记录器的字段的名称.

我在这个例子中使用了Log4j,但是我认为它应该与slf4j完全一样.

http://stackoverflow.com/questions/3038179/spring-constructor-injection-of-slf4j-logger-how-to-get-injection-target-class

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – Spring构建器注入SLF4J记录器 – 如何获取注入目标类?