Devrait Guice Fournisseurs cher membre des instances être annotée avec @Singleton?
Devrait Guice Fournisseurs de être annotée avec @Singleton
? Ma justification: si le Fournisseur est de fournir un objet à d'autres classes Singleton et l'objet lui-même est relativement coûteux à créer, alors ne serait-il pas logique d'utiliser un Singleton Fournisseur qui construit le cher objet de ses @Inject
marqué constructeur, le stocker en tant que membre et il suffit de retourner que déjà enregistré variable globale dans la lecture? Quelque chose comme ceci:
@Singleton
public class MyProvider extends Provider<ExpensiveObject> {
private ExpensiveObject obj;
@Inject
public MyProvider() {
/* Create the expensive object here, set it to this.obj */
}
@Override
public ExpensiveObject get() {
return obj;
}
}
Mise à jour
Permettez-moi de clarifier un peu plus ici. Ce n'est pas sur de savoir si je dois utiliser @Singleton
ou .in(Singleton.class)
. Cela doit faire plus avec la "mise en cache" de l'objet créé.
Disons que la création d'un objet nécessaire la création de plusieurs Rpc complets, tels que la désérialisation JSON ou de faire des requêtes HTTP. Cela pourrait prendre un certain temps. Si je vais utiliser ce Fournisseur pour les injecter dans des classes à plusieurs reprises, n'est-il pas logique de n'en créer qu'un tel objet?
Notez également que je dois être capable de faire appel à un Prestataire parce que j'ai besoin pour être en mesure de les injecter dans le Fournisseur.
OriginalL'auteur ecbrodie | 2013-12-09
Vous devez vous connecter pour publier un commentaire.
Si votre question est de savoir si vous devez créer d'étendue de fournisseur de liaisons, ou si vous devez instances de cache dans votre fournisseurs manuellement, alors vraiment, ne pas essayer d'être plus intelligent que Guice 🙂 Vous n'avez pas vraiment envie de faire quelque chose de plus que juste de créer votre cher objet dans
get()
méthode. Simple cas de test:Vous voir, parce que le message a été imprimé qu'une seule fois,
MyProvider.get()
méthode a été appelée qu'une fois de trop, justement à cause deString
est lié à portée singleton.Le concept clé pour comprendre ici est que les fournisseurs et les liaisons ne sont pas des entités séparées. Avec chaque liaison, il est associé à un fournisseur (lorsque vous créez de la plaine des liaisons avec
to()
, implicite fournisseur est créée pour vous). Cela peut facilement être observée à partir degetProvider()
signature de la méthode - il accepteClass<T>
ouKey<T>
pour la classe réelle que vous voulez avoir, pas pour le prestataire que vous avez lié. Lorsque vous créez une liaison fournisseur spécifique, vous ne configurez pas ce fournisseur, vous pouvez configurer la liaison. Guice est assez intelligent pour prendre étendues en compte, même si vous utilisez explicite fournisseurs, de sorte que vous n'avez pas besoin de réinventer la roue et le déploiement de votre propre singleton.Si votre question est plus précisément sur l'utilisation de
@Singleton
annotation (par opposition àbind()
DSL), alors je ne sais pas si sa présence sur le fournisseur de la classe donne aucun effet, mais étant donné que vous devez utiliserbind().toProvider()
lier à ce fournisseur de toute façon, je ne pense pas que cela compte vraiment. Utilisez simplementin()
méthode, il va certainement travailler.OriginalL'auteur Vladimir Matveev
Veuillez noter qu'il existe une différence majeure entre la liaison de votre fournisseur pour le Singleton portée par l'aide de
.in(Singleton.class)
et à l'aide de la@Singleton
annotation sur votre fournisseur de classe.get()
méthode n'est appelée qu'une fois et le résultat sera stocké dans la portée Singleton.get()
méthode est appelée pour chaque point d'injection dans votre application.Si vous utilisez cette approche, il serait sage d'manuellement le cache de votre cher objet. Mais il n'y a pas de point à le faire, vraiment. Utilisez simplement la première approche, et vous êtes très bien.
Vous pouvez même combiner les deux stratégies, par exemple en annotant le fournisseur avec
@Singleton
et de lier le fournisseur suite à la demande portée par l'aide de.in(RequestScoped.class)
. Sans l'annotation votre fournisseur va être instancié pour chaque demande, ce qui peut importe si il stocke dynamique de données.C'est juste une clarification de ce que certains lecteur peut par hasard sur votre question et peut penser que les deux approches sont sematically égalité.
OriginalL'auteur Daniel Beer
Oui, en principe, mais alors dans ce cas, vous pourriez finir avec le fournisseur de tout et il suffit de créer
ExpensiveObject
qu'un vif singleton. Il va seulement être instancié une seule fois lorsque l'injecteur est créé, et que seule instance obtenir injecté partout où il est nécessaire.ObjectMapper
à partir de la Jackson JSON l'analyse de la bibliothèque) pour créer monExpensiveObject
exemple, je voudrais donc encore besoin d'utiliser le fournisseur, n'aurais-je pas?OriginalL'auteur Chris Mantle