【问题标题】:Guice , afterPropertiesSetGuice , afterPropertiesSet
【发布时间】:2011-09-25 05:03:57
【问题描述】:

有人知道如何在 Guice 中实现与 spring 中的“afterPropertiesSet”接口相同的功能? (它是一个后期施工挂钩)

【问题讨论】:

  • 你指的接口是InitializingBean

标签: java guice


【解决方案1】:

到目前为止,最简单的解决方案是,如果您正在使用构造函数注入并且没有做任何过于疯狂的事情,那就是创建一个构造后方法并使用 @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@ 方法可能不能保证最后被调用)。也就是说,无论如何,构造函数注入都是首选方法,所以这应该不是问题。

【讨论】:

    【解决方案2】:

    我想使用@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 中的首选方法
    • 我只是不明白,我是否必须下载一些补丁来添加对这个 JRS 注释的支持?
    【解决方案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 模块中。玩得开心

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-02
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 2012-02-24
        • 2012-07-24
        • 2011-04-01
        相关资源
        最近更新 更多