【发布时间】:2011-09-25 05:03:57
【问题描述】:
有人知道如何在 Guice 中实现与 spring 中的“afterPropertiesSet”接口相同的功能? (它是一个后期施工挂钩)
【问题讨论】:
-
你指的接口是
InitializingBean
有人知道如何在 Guice 中实现与 spring 中的“afterPropertiesSet”接口相同的功能? (它是一个后期施工挂钩)
【问题讨论】:
InitializingBean
到目前为止,最简单的解决方案是,如果您正在使用构造函数注入并且没有做任何过于疯狂的事情,那就是创建一个构造后方法并使用 @Inject 对其进行注释:
final class FooImpl implements Foo {
private final Bar bar;
@Inject
FooImpl(Bar bar) {
this.bar = bar;
...
}
@Inject
void init() {
// Post-construction code goes here!
}
}
当 Guice 提供 FooImpl 时,它会看到它有一个 @Inject 构造函数,调用它,然后搜索带有 @Inject 注释的方法并调用它们。预期的用例是 setter 注入,但即使 @Inject 方法没有参数,Guice 也会调用它。
如果您使用 setter 或字段注入来注入 deps,我不建议使用它,因为我不知道 Guice 是否对调用 @Inject 方法的顺序做出任何保证(即您的 @ 987654327@ 方法可能不能保证最后被调用)。也就是说,无论如何,构造函数注入都是首选方法,所以这应该不是问题。
【讨论】:
我想使用@PostConstruct 是可行的方法。
这是一篇相关的博文:http://macstrac.blogspot.com/2008/10/adding-support-for-postconstruct.html
这是一个提供支持的插件库:http://code.google.com/p/guiceyfruit/
这里描述了通过 Guiceyfruit 添加生命周期支持:http://code.google.com/p/guiceyfruit/wiki/Lifecycle
【讨论】:
@PostConstruct 也是 Spring 中的首选方法
它似乎还不支持,所以对于每个人都希望这项工作,这里是一个小解决方案。
public class PostConstructListener implements TypeListener{
private static Logger logger = Logger.getLogger(PostConstructListener.class);
@Override
public <I> void hear(TypeLiteral<I> iTypeLiteral,final TypeEncounter<I> iTypeEncounter) {
Class<? super I> type = iTypeLiteral.getRawType();
ReflectionUtils.MethodFilter mf = new ReflectionUtils.MethodFilter() {
@Override
public boolean matches(Method method) {
return method.isAnnotationPresent(PostConstruct.class);
}
};
ReflectionUtils.MethodCallback mc = new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if (!(method.getReturnType().equals(Void.TYPE) && method.getParameterTypes().length == 0))
{
logger.warn("Only VOID methods having 0 parameters are supported by the PostConstruct annotation!" +
"method " + method.getName() + " skipped!");
return;
}
iTypeEncounter.register(new PostConstructInvoker<I>(method));
}
};
ReflectionUtils.doWithMethods(type,mc,mf);
}
class PostConstructInvoker<I> implements InjectionListener<I>{
private Method method;
public PostConstructInvoker(Method method) {
this.method = method;
}
@Override
public void afterInjection(I o) {
try {
method.invoke(o);
} catch (Throwable e) {
logger.error(e);
}
}
}
}
ReflectionUtils 包是在 spring 中定义的。
将此侦听器绑定到任何事件:
bindListener(Matchers.any(),new PostConstructListener());
在您的 guice 模块中。玩得开心
【讨论】:
您需要阅读 Guice wiki 上的 CustomInjections 页面:
除了标准的
@Inject驱动的注入之外,Guice 还包括用于自定义注入的钩子。这使 Guice 能够托管具有自己的注入语义或注释的其他框架。大多数开发人员不会直接使用自定义注入;但他们可能会在扩展和第三方库中看到它们的用途。每个自定义注入都需要一个类型侦听器、一个注入侦听器,并分别注册。
【讨论】: