2013-02-23 7 views
14

Ich bin neu im Frühling Rahmen, begann mit einigen Tutorials, um es zu lernen.Spring Bean Zerstörungsmethode, Singleton und Prototyp Scopes

Ich habe folgende Dateien,

# 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> 

Als ich scope="singleton" nehmen meine Ausgang:

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

Wenn ich nehme scope="prototype" meine Ausgabe lautet:

xml configured initialize 
Inside setMessage 
Your Message : My message 

xmlDestroy() Methode mit singleton Umfang Bean genannt wird, aber nicht mit prototype mir freundlich für die folgenden helfen,

Ist das ist richtig? Wenn ja, was wären mögliche Gründe?

Auch habe ich einige Anfragen wie,

Was ist der Unterschied oder Beziehung zwischen ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext

Antwort

34

xmlDestroy() Methode wird mit Singletons Umfang Bean genannt, aber nicht mit Prototyp weil

Frühling den gesamten Lebenszyklus eines Prototyps Bean nicht verwalten hat: die Container Instantiiert, konfiguriert ziert und montiert sonst ein Prototyp-Objekt, übergibt es an der Client und hat dann keine weiteren Kenntnisse dieser Prototypinstanz. Um Ressourcen freizugeben, versuchen Sie, einen benutzerdefinierten Bean-Post-Prozessor zu implementieren.

Im Gegensatz zu Singletons Bohnen, wo die Feder Container den gesamten Lebenszyklus verwaltet

Sie einen Blick auf diese Grund tutorial für Unterschiede zwischen den verschiedenen Kontexten haben

Siehe documentation

+0

Für die Freigabe von Ressourcen kann der DestructionAwareBeanPostProcessor anstelle eines normalen BeanPostProcessor implementiert werden. –

1

Dies ist das erwartete Verhalten. Es gibt keine Möglichkeit für Spring, zu wissen, wann Sie eine Prototypbereichs-Bean verwendet haben, so dass die Bean-Destruktion nicht von Spring für Prototyp-Beans verwaltet wird. Aus der Dokumentation:

Obwohl Initialisierung Lifecycle-Callback-Methoden auf alle Objekte aufgerufen werden, unabhängig von Umfang, in dem Fall von Prototypen, konfigurierten Zerstörung Lifecycle Rückrufe werden nicht genannt.

Weitere Informationen finden Sie unter Spring documentation.

In Bezug auf ApplicationContext s können Sie diejenige auswählen, die für Ihre Anwendung am besten geeignet ist. Dies hängt davon ab, ob Sie XML- oder Annotation-Bean-Konfigurationen verwenden möchten und ob Sie beispielsweise in einem Servlet-Container ausgeführt werden. ApplicationContext selbst ist die Schnittstelle an der Wurzel der Typherarchie.

2

A Singleton Bohne bedeutet, dass Es gibt genau eine Instanz dieser Bean im Anwendungskontext. Das bedeutet, wenn Sie so etwas tun:

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()); 

Sie sehen "Meine Nachricht" in der Konsole zweimal ausgegeben.

Für Prototyp-Beans jedes Mal, wenn Sie versuchen, einen aus dem Anwendungskontext zu bekommen, erhalten Sie eine neue Instanz. Wenn Sie den obigen Code erneut ausführen, wird die zweite Konsolenausgabe "null" sein.

Da der Container eine destroy-Methode für eine Prototyp-Bean nicht aufrufen muss, ist dies nicht der Fall und das Verhalten ist korrekt.

Der Unterschied zwischen den genannten Klassen ist, dass sie eine Schnittstelle, eine abstrakte Klasse bzw. eine konkrete Klasse sind, um besser über diese Konzepte zu verstehen, empfehle ich, die offizielle Orakeldokumentation für Java hier zu lesen Oracle Java Tutorials.

-1

Bitte überprüfen Sie Ihren Scope-Typ in Ihrer Spring-Konfigurationsdatei. Wenn scope = „Prototyp“ dann zu Umfang ändern = „Singletons“

<bean id="helloWorld" class="com.example.test.HelloWorld" 
init-method="init" destroy-method="destroy"> 
<property name="message" value="Hello World!" /> 

0

Ich habe versucht, auch ein Ereignis von Bohnen zerstören zu bekommen, den Umfang ist die „Prototyp“. Also lese ich alle Antworten oben und versuche durch ihre Antworten. Als Ergebnis erreiche ich, dass es keine Möglichkeit gibt, eine Zerstörung von Prototyp-Bohnen zu erkennen.

Obwohl Initialisierungslebenszyklus-Rückrufmethoden für alle Objekte unabhängig vom Gültigkeitsbereich aufgerufen werden, werden im Fall von Prototypen keine konfigurierten Destruktionslebenszyklusrückrufe aufgerufen.

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

1

Ihre Anwendung für neue Instanzen von Prototypen Bohnen fragen konnte alle 10 Millisekunden, was mit der Bohne tun, und es dann außerhalb des Gültigkeitsbereiches gehen lassen. Wenn Spring sie zerstören musste(), wenn die Anwendung heruntergefahren wurde, musste sie einen Verweis auf jede erstellte Prototyp-Bean behalten, was verhinderte, dass sie als Müll gesammelt wurden und somit einen Speicherverlust verursachten.

Verwandte Themen