Guice , afterPropertiesSet

前端 未结 4 481
不思量自难忘°
不思量自难忘° 2021-01-07 05:19

Someone knows some way that how can I achieve the same functionality in Guice as the \'afterPropertiesSet\' interface in spring ? ( its a post construction hook )

相关标签:
4条回答
  • 2021-01-07 05:40

    You'll want to read the CustomInjections page on the Guice wiki:

    In addition to the standard @Inject-driven injections, Guice includes hooks for custom injections. This enables Guice to host other frameworks that have their own injection semantics or annotations. Most developers won't use custom injections directly; but they may see their use in extensions and third-party libraries. Each custom injection requires a type listener, an injection listener, and registration of each.

    0 讨论(0)
  • 2021-01-07 05:45

    I guess using @PostConstruct is the way to go.

    Here is a related blog post : http://macstrac.blogspot.com/2008/10/adding-support-for-postconstruct.html

    And here is an addon library that provides the support : http://code.google.com/p/guiceyfruit/

    Adding lifecycle support via Guiceyfruit is described here : http://code.google.com/p/guiceyfruit/wiki/Lifecycle

    0 讨论(0)
  • 2021-01-07 05:47

    By far the simplest solution, if you're using constructor injection and not doing anything too crazy, is to create a post-construction method and annotate it with @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!
      }
    }
    

    When Guice provides FooImpl, it'll see it has an @Inject constructor, call it, and then search for methods annotated with @Inject and call those. The intended use case for this is setter injection, but even if an @Inject method has no params, Guice will call it.

    I don't recommend using this if you're using setter or field injection to inject deps since I don't know if Guice makes any guarantees about the order in which @Inject methods are called (that is, your init() method might not be guaranteed to be called last). That said, constructor injection is the preferred approach anyway, so that should be a non-issue.

    0 讨论(0)
  • 2021-01-07 05:48

    It seems it is not yet supported , so for everyone how wants this work , here is small solution.

    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);
                }
            }
        }
    }
    

    The ReflectionUtils package is defined in spring.

    Bind this listener to any event with :

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

    in your guice module. Have fun

    0 讨论(0)
提交回复
热议问题