Guice,afterPropertiesSet

时间:2010-05-26 11:04:34

标签: java guice

有人知道如何在Guice中实现与Spring中的“afterPropertiesSet”界面相同的功能? (它是一个建筑后的钩子)

4 个答案:

答案 0 :(得分:8)

到目前为止,最简单的解决方案,如果你正在使用构造函数注入而不做任何过于疯狂的事情,那就是创建一个构造后的方法并用@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方法没有params,Guice也会调用它。

如果您使用setter或字段注入来注入deps,我不建议使用它,因为我不知道Guice是否对调用@Inject方法的顺序做出任何保证(即,您的init()方法可能无法保证最后调用。也就是说,无论如何,构造函数注入是首选方法,因此这应该是一个非问题。

答案 1 :(得分:5)

我想使用@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

答案 2 :(得分:3)

它似乎尚未得到支持,因此对于每个人来说,如果想要这样做,这是一个小解决方案。

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模块中。玩得开心

答案 3 :(得分:3)

您需要阅读Guice wiki上的CustomInjections页面:

  

除标准@Inject驱动的注射外,Guice还包括用于自定义注射的钩子。这使Guice能够托管具有自己的注入语义或注释的其他框架。大多数开发人员不会直接使用自定义注射;但是他们可能会在扩展和第三方库中看到它们的用途。每个自定义注入都需要一个类型侦听器,一个注入侦听器和每个注册侦听器。