web-dev-qa-db-fra.com

Méthode de destruction des haricots printaniers, singleton et prototypes

Je suis nouveau dans le framework Spring, j'ai commencé avec quelques tutoriels pour l'apprendre.

J'ai les fichiers suivants,

# MainProgram.Java

package test.spring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainProgram {
        public static void main(String[] args) {
              AbstractApplicationContext context = 
                              new ClassPathXmlApplicationContext("Bean.xml");     
              HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
              obj.setMessage("My message");
              obj.getMessage();
              context.registerShutdownHook();

        }
 }

# HelloSpring.Java

package test.spring;

public class HelloSpring   {
     private String message;

     public void setMessage(String message){
      this.message  = message;
      System.out.println("Inside setMessage");
   }

   public void getMessage(){
      System.out.println("Your Message : " + this.message);
   }

   public void xmlInit() {
    System.out.println("xml configured  initialize");
   } 

    public void xmlDestroy() {
    System.out.println("xml configured destroy");
    }

  }

# Bean.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

     <bean id="helloSpring" class="test.spring.HelloSpring" 
          scope="prototype" init-method="xmlInit" destroy-method="xmlDestroy">

     </bean>
     </beans>

Quand je prends scope="singleton", ma sortie est:

 xml configured  initialize
 Inside setMessage
 Your Message : My message
 xml configured destroy

Quand je prends scope="prototype", ma sortie est:

 xml configured  initialize
 Inside setMessage
 Your Message : My message

La méthode xmlDestroy() est appelée avec singleton scope bean mais pas avec prototype veuillez m'aider avec bonté pour les points suivants,

Est-ce correct? Si oui, quelles seraient les raisons possibles?

J'ai aussi des questions comme

quelle est la différence ou la relation entre ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext

17
Nikhil Rupanawar

La méthode xmlDestroy() est appelée avec bean singleton scope mais pas avec prototype car 

Spring ne gère pas le cycle de vie complet d'un prototype de haricot: le conteneur instancie, configure, décore et assemble autrement un objet prototype, le remet au client et n'a ensuite aucune autre connaissance de cette instance de prototype. Pour libérer des ressources, essayez d'implémenter un post-processeur de bean personnalisé. 

Contrairement aux haricots singleton où le récipient de printemps gère le cycle de vie complet 

Vous pouvez jeter un oeil à ce - tutorial de base pour connaître les différences entre différents contextes 

Référez-vous documentation

38
Manish Singh

C'est le comportement attendu. Spring ne dispose d'aucun moyen de savoir si vous avez fini d'utiliser un haricot scope prototype. Par conséquent, la destruction des haricots n'est pas gérée par Spring pour les haricots à portée prototype. De la documentation:

Bien que les méthodes de rappel du cycle de vie d'initialisation soient appelées sur tous les objets Quelle que soit leur portée, dans le cas des prototypes, les rappels de cycle de vie de destruction configurés Ne sont pas appelés.

Voir la Documentation Spring pour plus d'informations.

En ce qui concerne ApplicationContexts, vous pouvez choisir celui qui convient le mieux à votre application. Cela dépend si vous voulez utiliser XML ou une configuration de bean annotation, et si vous exécutez ou non dans un conteneur de servlet, par exemple. ApplicationContext est lui-même l'interface à la racine du type heirarchy.

2
hertzsprung

Un bean singleton signifie qu'il existe exactement une instance de ce bean dans le contexte de l'application. Cela signifie que si vous faites quelque chose comme ça:

HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
    obj.setMessage("My message");
    System.out.printIn(obj.getMessage());
    HelloSpring anotherObj = (HelloSpring) context.getBean("helloSpring");
    System.out.printIn(anotherObj.getMessage());

Vous verrez deux fois "Mon message" dans la sortie de la console. 

Pour les prototypes de haricots chaque fois que vous essayez d'obtenir l'un de ceux-ci à partir du contexte d'application, vous obtiendrez une nouvelle instance. Ainsi, si vous exécutez à nouveau le code ci-dessus, la deuxième sortie de la console sera "null".

Comme le conteneur n'a pas besoin d'appeler une méthode de destruction pour un haricot prototype, il ne le fait pas et le comportement est correct.

La différence entre lesdites classes est qu’il s’agit d’une interface, d’une classe abstraite et d’une classe concrète, afin de mieux comprendre ces concepts, je suggère de lire la documentation officielle Oracle pour Java ici Tutoriels Oracle Java .

2
Can Yegane

votre application peut demander de nouvelles instances de prototype de haricots toutes les 10 millisecondes, faire quelque chose avec le haricot, puis le laisser sortir de son champ d'application. Si Spring devait les détruire () à la fermeture de l'application, il devrait conserver une référence à chaque bean prototype créé, ce qui les empêcherait d'être récupérés, ce qui causerait une fuite de mémoire.

2
Vishwanath Sharma

J'ai également essayé d'obtenir un événement de destruction de haricot dont la portée est "prototype". J'ai donc lu toutes les réponses ci-dessus et j'essaie par leurs réponses. Au final, je montre qu'il n'y a pas moyen détecter une destruction même de prototype de haricot.

Bien que les méthodes de rappel du cycle de vie d'initialisation soient appelées sur tous les objets, quelle que soit leur portée, dans le cas de prototypes, les rappels de cycle de vie de destruction configurés ne sont pas appelés.

voir ici ( https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype )

0
Liu Zhe