2010-05-26 12 views
2

Quelqu'un sait d'une certaine manière comment puis-je obtenir la même fonctionnalité dans Guice que l'interface 'afterPropertiesSet' au printemps? (c'est un crochet de post-construction)Guice, afterPropertiesSet

+1

L'interface dont vous parlez est 'InitializingBean' – skaffman

+0

Oui, le lien est là pour – Roman

Répondre

3

Il semble qu'il est pas encore pris en charge, donc pour tout le monde comment veut ce travail, voici une petite 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); 
      } 
     } 
    } 
} 

Le paquet ReflectionUtils est défini au printemps.

Bind cet écouteur à tout événement avec:

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

dans votre module Guice. Amusez-vous

5

Je suppose que l'utilisation de @PostConstruct est la voie à suivre.

Voici un blog lié: http://macstrac.blogspot.com/2008/10/adding-support-for-postconstruct.html

Et voici une bibliothèque addon qui fournit le support: http://code.google.com/p/guiceyfruit/

Ajout du support du cycle de vie via Guiceyfruit est décrit ici: http://code.google.com/p/guiceyfruit/wiki/Lifecycle

+0

' @ PostConstruct' est l'approche préférée au printemps, aussi – skaffman

+0

Je ne comprends pas, dois-je télécharger un patch pour ajouter support pour ces annotations JRS? – Roman

3

Vous voulez lire la page sur le wiki CustomInjections Guice:

En plus des standards @Inject -Driven injections, Guice comprend des crochets pour les injections personnalisées. Cela permet à Guice d'héberger d'autres frameworks ayant leurs propres sémantiques d'injection ou annotations. La plupart des développeurs n'utiliseront pas directement les injections personnalisées; mais ils peuvent voir leur utilisation dans les extensions et les bibliothèques tierces. Chaque injection personnalisée nécessite un écouteur de type, un écouteur d'injection et l'enregistrement de chacun.

8

De loin le est de créer une méthode de post-construction et annoter avec @Inject solution la plus simple, si vous utilisez l'injection de constructeur et ne pas faire quoi que ce soit trop fou,:

final class FooImpl implements Foo { 
    private final Bar bar; 

    @Inject 
    FooImpl(Bar bar) { 
    this.bar = bar; 

    ... 
    } 

    @Inject 
    void init() { 
    // Post-construction code goes here! 
    } 
} 

Lorsque Guice fournit FooImpl, il verra qu'il a un constructeur @Inject, appelez-le, puis recherchez les méthodes annotées avec @Inject et appelez ceux-ci. Le cas d'utilisation prévu pour ceci est l'injection de setter, mais même si une méthode @Inject n'a pas de paramètres, Guice l'appellera. Je ne recommande pas d'utiliser ceci si vous utilisez un setter ou une injection sur le terrain pour injecter des deps car je ne sais pas si Guice donne des garanties quant à l'ordre dans lequel les méthodes @Inject sont appelées (c'est-à-dire votre méthode init() pourrait ne pas être garanti d'être appelé en dernier). Cela dit, l'injection par le constructeur est de toute façon l'approche préférée, donc cela ne devrait pas être un problème.