2010-09-30 7 views
3

J'ai créé un prototype de bean tronqué dans mon application et je l'injecte à un autre bean à l'aide d'un setter. Mais quand j'utilise le bean injecté dans ma classe, il utilise toujours la même instance à la place de la nouvelle instance à chaque fois.La portée du prototype ne fonctionne pas

Voici un aperçu du code

<bean name="prototypeScope" Class="A" scope="prototype"> 
</bean> 

<bean Class="Consumer"> 
    <property name="a" ref="prototypeScope" /> 
</bean> 

public class Consumer{ 
    privare A a; 

    public void setA(A a){ 
     this.a = a; 
    } 


    public void consume(){ 

     a.doSomething(); 

    } 
} 

Cordialement

Répondre

6

Il est une erreur commune concernant un prototype de haricots scope.

Une nouvelle instance du bean du prototype sera créée uniquement lorsque nous demandons une copie du bean du contexte de l'application, et non chaque fois que nous appelons une méthode sur l'instance.

Dans votre cas, vous êtes en train d'injecter le bean du prototype à un autre bean en utilisant le setter de ce dernier, alors la seconde classe est créée et une nouvelle instance du bean du prototype est créée. Mais il utilisera la même instance tant qu'il est remplacé par un autre insta mannualy par vous.

Si vous voulez une nouvelle instance du prototype de bean pendant une opération particulière comme un appel de méthode, vous devez obtenir une nouvelle instance du bean à partir du contenu de l'application.

Ex:

<bean name="prototypeScope" Class="A" scope="prototype"> 
</bean> 

<bean Class="Consumer"> 
</bean> 

code Java:

public class Consumer implements ApplicationContextAware{ 
    privare ApplicationContext context; 

    public void setApplicationContext(ApplicationContext context){ 
     this.context = context; 
    } 


    public void consume(){ 

     A a = context.getBean("prototypeScope", A.class); 

     a.doSomething(); 

    } 
} 

Dans cet exemple, chaque fois que la méthode est appelée consommer une nouvelle instance de la classe A est créée.

+0

Je diviser le code source en deux parties. Si vous utilisez deux langues différentes dans la même liste, la coloration syntaxique ne fonctionne pas correctement. –

2

Il existe deux manières principales de traiter le problème de dépendance Singleton-Bean-has-Prototype.

Un est étroitement couplé à l'applicationContext, comme dans Ram's answer, l'autre est Lookup Method Injection.

Fondamentalement, vous faites votre classe de haricot abstraite et ajouter une méthode abstraite pour la dépendance, quelque chose comme ceci:

public abstract class MyBean{ 

    public abstract MyService lookupService(); 

} 

vous ajoutez ensuite une définition de haricot quelque chose comme ceci:

<bean id="myBean" class="fiona.apple.sucks.MyBean"> 
<!-- sorry, just wanted to insert sucks after Spring's fiona apple example, 
didn't think about the connotations :-) --> 
    <lookup-method name="lookupService"/> 
</bean> 

maintenant Spring créera une sous-classe CGLib de votre classe bean qui renverra une nouvelle instance Prototype à chaque fois que vous appellerez myBean.lookupService().

1

J'ai utilisé une telle approche une fois ..

D'abord, je déclare un haricot

<bean id="notSingelton" class="com.Foo" singleton="false" /> 

a ensuite fait une interface

public interface FooFactory { 
    Foo make(String name); 
} 

enveloppées dans ServiceLocatorFactoryBean

<bean id="fooFactory" 
    class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"> 
    <property name="serviceLocatorInterface" value="com.FooFactory" /> 
</bean> 

<bean id="consumer" class="com.Consumer"> 
    <constructor-arg ref="fooFactory" /> 
</bean> 

et la classe des consommateurs avait l'air quelque chose comme ça:

public class Consumer { 
    private FooFactory fooFactory; 

    public Consumer(FooFactory fooFactory) { 
     this.fooFactory = fooFactory; 
    } 


    public void consume(){ 
     Foo foo = fooFactory.make("notSingelton"); 
     foo.doSomething(); 
    } 
} 
Questions connexes