几天以来,我一直在使用google-guice,并且给我留下了越来越多的印象。
我创建了一个MemberInjector来轻松集成日志记录框架SLF4J,只需添加一个附加注释即可。这意味着不要总是长期使用:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
我现在正在使用:
@Log
Logger LOG;
这真的很棒,但是:
我还在同一个类中使用方法注入作为这种启动函数,并且如果我在那里访问LOG实例,则会导致NPE!因为还没有注入。
@Inject
public void start() {
//And here is the problem...
LOG.info("in start") //causes NPE, cause LOG is not injected yet
}
如果我在其他(非注入)方法中使用LOG实例,则它可以正常工作。
是否可以更改注入顺序,还是可以告诉guice提前注入MemberInjector?原因我真的很想在方法注入部分中也使用日志记录。
感谢任何提示。
答案 0 :(得分:0)
我发现的一个解决方案是只创建一个附加的侦听器,以查找已定义的方法(例如“ init”或“ start”),并在创建和注入成员后调用它。
请参阅模块配置:
@Override
protected void configure() {
bindListener(Matchers.any(), new InitMethodTypeListener());
//...
InitMethodTypeListener:
public class InitMethodTypeListener implements TypeListener {
private static final Logger log = LoggerFactory.getLogger(InitMethodTypeListener.class);
@SuppressWarnings("rawtypes")
static class InitInvoker implements InjectionListener {
@Override
public void afterInjection(final Object injectee) {
try {
log.info("Invoke init() from Class: {}", injectee.getClass().getName());
injectee.getClass().getMethod("init").invoke(injectee);
} catch (final Exception e) {
log.error(e.getMessage(), e);
}
}
public static final InitInvoker INSTANCE = new InitInvoker();
}
@SuppressWarnings("unchecked")
@Override
public <I> void hear(final TypeLiteral<I> type, final TypeEncounter<I> encounter) {
try {
if (type.getRawType().getMethod("init") != null) {
encounter.register(InitInvoker.INSTANCE);
}
} catch (final NoSuchMethodException | SecurityException e) {
// do nothing here, if not init-method found - no call
}
}
}
也许这不是直接的方法,但是它可行。因此,我确信在调用init方法时,所有成员都注入良好。
通过此实现,所有受guice控制的对象的“初始化”方法将在对象创建和注入后自动调用。