Guice, afterPropertiesSet - PullRequest
       9

Guice, afterPropertiesSet

2 голосов
/ 26 мая 2010

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

Ответы [ 4 ]

8 голосов
/ 22 сентября 2011

Самое простое решение, если вы используете инжектор конструктора и не делаете ничего сумасшедшего, - это создать метод пост-построения и аннотировать его с помощью @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 инъекцию для ввода deps, поскольку я не знаю, дает ли Guice какие-либо гарантии порядка, в котором вызываются методы @Inject (то есть ваш 1011 * метод не может быть гарантированно вызван последним). Тем не менее, инъекция в конструктор является предпочтительным подходом в любом случае, так что это не должно быть проблемой.

5 голосов
/ 26 мая 2010

Я думаю, использование @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

3 голосов
/ 26 мая 2010

Вам нужно прочитать страницу CustomInjection на вики Guice:

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

3 голосов
/ 26 мая 2010

Кажется, что это еще не поддерживается, поэтому для всех, кто хочет эту работу, вот небольшое решение.

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

Свяжите этого слушателя с любым событием с помощью:

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

в вашем модуле guice. Веселись

...