2009-01-24 7 views
8

Je dois obtenir le contexte de l'application printanière à partir d'un objet non bean. Dans un autre thread de SO, la réponse acceptée suggère d'utiliser singleton pour obtenir le contexte de l'application. Getting Spring Application ContextObtention du contexte Spring Application à partir d'un objet non bean sans utiliser Singleton

Mais l'utilisation singleton rend mon code plus couplé et moins testable, les problèmes habituels ont discuté dans de nombreux sujets (par exemple What is so bad about Singletons)

La question, est-il un moyen élégant pour obtenir le contexte d'application à partir d'un haricot non objet sans utiliser singleton?

Répondre

7

Il y a toujours le problème d'amorçage. Pour les applications Web, le filtre de servlet externe gère généralement la situation.

Si ce n'est pas une application web, il n'y a aucun moyen de contourner une sorte de singleton externe ou de bootstrapper. Mais; l'utilisation d'un singleton ici ne devrait affecter que la testabilité de cette classe unique de bootstrappers. Il ne devrait vraiment y avoir que très peu d'endroits dans votre code qui ont besoin de référencer le conteneur de manière explicite. Donc, cela n'augmente pas vraiment le couplage de manière significative.

Ou pour reformuler, il devrait y avoir seulement très peu d'objets non-haricots qui doivent accéder au conteneur de ressort. Si ce n'est pas le cas, vous n'utilisez probablement pas le ressort de manière optimale. Et la plupart/tous ceux qui ont besoin du conteneur devraient probablement mettre en œuvre BeanFactoryAware ou ApplicationContextAware

+0

+1 sur ce point. Les singletons devraient généralement être évités dans votre code d'application. Pour certains types de bootstrap ou d'infrastructure, ce n'est pas une grosse affaire. Les chances sont que vous n'aurez pas besoin de tester votre bootstrappeur de toute façon. :) –

7

Je pense que votre problème est à peu près le même que j'avais quelques jours en arrière. Je pense que ce qui suit devrait travailler pour vous:

D'abord créer une classe appelée AppContextManager comme ci-dessous:

@Component 
public class AppContextManager implements ApplicationContextAware{ 
    private static ApplicationContext _appCtx; 

    @Override 
    public void setApplicationContext(ApplicationContext ctx){ 
     _appCtx = ctx; 
    } 

    public static ApplicationContext getAppContext(){ 
     return _appCtx; 
    } 
} 

Annoter la classe ci-dessus avec @Component ou déclare un haricot pour AppContextManager dans votre application context xml.

maintenant dans votre non-singletonnon-spring exemple, utiliser l'extrait de code suivant pour obtenir tout autre grain printemps:

ApplicationContext ctx = ApplicationContextManager.getAppContext(); 
SomeSpringBean bean = ctx.getBean(SomeSpringBean.class); 

Et cela vous donne l'exemple de haricots partout dans votre code.

+1

Cela n'a pas fonctionné. –

+1

avez-vous créé votre bean correctement pour AppContextManager .. soit votre bean devrait être dans un paquet sous la configuration définie par le paquet 'component scan base package' ou déclarer un bean pour le même dans votre contexte d'application xml. – mickeymoon

+0

@mickeymoon merci pour la réponse, c'est vraiment m'aider. –

Questions connexes