5
votes

Quelle est la meilleure pratique: utilisez le bean prototype au lieu de l'opérateur new ()

J'essaie de comprendre quelle serait l'utilisation correcte du bean prototype Spring. Peut-être que l'exemple de code suivant vous aidera à comprendre mon dilemme:

List<ClassA> caList = new ArrayList<ClassA>();
    for (String name : nameList) {
        ClassA ca = new ClassA();

    //or Shall I use protypebean, using method lookup I can inject the dependency of ClassA. 
    // ClassA ca = getPrototypeClassA();

        ca.setName(name);
        caList.add(ca);
    }

Donc, mon point exact est dans ce scénario, je vais utiliser l'injection de méthode ou l'opérateur new (). Justifiez votre point de vue.


1 commentaires

Avez-vous quelque chose à injecter? Ne pouvez-vous pas séparer les choses que vous devez injecter de l'état mutable si l'objet (si vous le pouvez, être à côté du bean sans état) - alors vous pouvez utiliser un bean prototype.


3 Réponses :


4
votes

Vous pouvez utiliser l'une ou l'autre des méthodes, car en fin de compte, le code client est responsable de la gestion du cycle de vie du prototype bean plutôt que du conteneur à ressort.

Selon Spring-docs,

À certains égards, vous pouvez penser au rôle des conteneurs Spring lorsque parler d'un haricot à portée de prototype comme un remplacement pour l'opérateur Java «nouveau». Tous les aspects du cycle de vie au-delà de ce point doivent être géré par le client.

Spring ne gère pas le cycle de vie complet d'un prototype de bean: le le conteneur instancie, configure, décore et assemble autrement un objet prototype, le remet au client et n'a plus connaissance de cette instance prototype. C'est la responsabilité du code client pour nettoyer les objets à portée prototype et libérer tout ressources chères que le (s) prototype (s) retiennent.


2 commentaires

Non, c'est bien, donc mon point de vue dans le projet de printemps, nous pouvons contourner les haricots à portée prototype dans tous les scénarios ... Il n'y a donc pas d'utilisation réelle du haricot prototype au printemps.


Si je choisis le nouveau, il incombe également à son développeur de libérer des ressources et de rendre l'objet éligible pour le ramasse-miettes, il est donc vraiment déroutant dans quel scénario nous devrions opter pour des prototypes de beans.



0
votes

Il semble que votre instance ait besoin de certaines valeurs d'exécution pour s'initialiser correctement. Dans ce cas, cela dépend si vous devez utiliser une fonction de ressort telle que AOP pour l'instance de ClassA. Si oui, optez pour la méthode injection.Sinon, vous pouvez envisager d'utiliser le modèle d'usine. Beaucoup plus OO et plus propre pour moi:

Quelque chose comme ce qui suit. Vous devriez avoir l'idée.

@Autowired
private FactoryForClassA factoryForClassA;

List<ClassA> caList = new ArrayList<ClassA>();
for (String name : nameList) {
    ClassA a = factoryForClassA.create(name);
    caList.add(ca);
}

Et le code client:

@Component
public class FactoryForClassA {

    @Autowired
    private FooBean someDependencyForClassA;


    public ClassA create(String name){
        ClassA a = new ClassA(someDependencyForClassA);
        a.setName(name);
        return a;
    }
}


0 commentaires

1
votes

Si ClassA doit avoir des références @Autowired , alors optez pour un bean prototype.

Sinon, un simple POJO (dont le conteneur Spring n'est pas au courant) fera l'affaire.


1 commentaires

Merci, nous n'utilisons en fait spring ioc que pour gérer nos singletons à ressort.