我有以下情况:
class MyClass implements MyInterface {
private Logger logger = Logger.getLogger(MyClass.class);
... methods ...
}
我认为如果我可以注入我的记录器而不是在类中创建它,那就太好了。
class MyClass implements MyInterface {
@Inject
private Logger logger;
... methods ...
}
有没有人知道Guice是否可以做这种事情?我一直在使用Guice一段时间,但是无法想出一种基于请求类的类类型注入字段的方法。
答案 0 :(得分:4)
这不仅可行,而且甚至在自定义注射下的Guice Wiki中有详细描述。有关log4j的完整示例,所有解释都有here。我已经在little projects到slf4j的一个中修改了这个例子,几乎没有任何努力,它运行正常。以下是slf4j的示例:
创建注释:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectLogger {
}
添加SLF4j类型侦听器:
public class SLF4JTypeListener implements TypeListener {
public <T> void hear(TypeLiteral<T> typeLiteral,
TypeEncounter<T> typeEncounter) {
// the class which members will be injected
Class<?> clazz = typeLiteral.getRawType();
while (clazz != null) {
//add listener for any field
Arrays.stream(clazz.getDeclaredFields())
.filter(this::isLoggerField)
.forEach(
f -> typeEncounter
.register(new SLF4JMembersInjector<T>(f)));
clazz = clazz.getSuperclass();
}
}
private boolean isLoggerField(Field f) {
return f.getType() == Logger.class
&& f.isAnnotationPresent(InjectLogger.class);
}
}
注射器本身:
public class SLF4JMembersInjector<T> implements MembersInjector<T> {
private final Field field;
private final Logger logger;
SLF4JMembersInjector(Field field) {
this.field = field;
this.logger = LoggerFactory.getLogger(field.getDeclaringClass());
field.setAccessible(true);
}
public void injectMembers(T t) {
try {
field.set(t, logger);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
最后我的模块中的绑定:
bindListener(Matchers.any(), new SLF4JTypeListener());
用法:
@InjectLogger
private Logger logger;