2010-05-26 3 views
2

Кто-то знает, как я могу достичь той же функциональности в Guice, что и «afterPropertiesSet» интерфейс весной? (его крюк для строительства)Guice, afterPropertiesSet

+1

вы имеете в виду это интерфейс 'InitializingBean' – skaffman

+0

Yep, ссылка там – Roman

ответ

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 определяется весной.

Bind этот слушатель к любому событию с:

bindListener(Matchers.any(),new PostConstructListener()); 

в модуле Guice. Весело

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

+0

' @ PostConstruct' является предпочтительным подходом весной, также – skaffman

+0

я просто не понимаю, я должен скачать некоторые патч, чтобы добавить поддержка этих аннотаций JRS? – Roman

3

Вы хотите прочитать CustomInjections страницы на вики Guice:

В дополнении к стандартным @Inject управляемому обществу инъекций, Guice включает крючки для пользовательских инъекций. Это позволяет Guice размещать другие структуры, которые имеют собственную семантику или аннотации инъекций. Большинство разработчиков не будут использовать пользовательские инъекции напрямую; но они могут видеть их использование в расширениях и сторонних библиотеках. Для каждой пользовательской инъекции требуется прослушиватель типа, прослушиватель инъекций и регистрация каждого из них.

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, и позвоните им. Предполагаемый прецедент для этого - инъекция установки, но даже если метод @Inject не имеет параметров, Guice назовет его.

Я не рекомендую использовать это, если вы используете setter или field injection для ввода deps, поскольку я не знаю, дает ли Guice какие-либо гарантии относительно порядка, в котором вызывается метод @Inject (т. Е. Ваш метод init() не может быть гарантированно называться последним). Тем не менее, инъекция конструктора является предпочтительным подходом, так что это должно быть проблемой.

Смежные вопросы