ti-enxame.com

Escopo do método de destruição, do singleton e do protótipo do bean de primavera

Eu sou novo no framework spring, comecei com alguns tutoriais para aprendê-lo.

Eu tenho os seguintes arquivos,

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

Quando eu pego scope="singleton", Minha saída é:

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

Quando eu pego scope="prototype", Minha saída é:

 xml configured  initialize
 Inside setMessage
 Your Message : My message

xmlDestroy() method é chamado com singleton scope bean, mas não com prototype gentilmente me ajude no seguinte,

Isso está correto? Nesse caso, quais seriam os possíveis motivos?

Também tenho algumas consultas como,

qual é a diferença ou relação entre ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext

22
Nikhil Rupanawar

O método xmlDestroy() é chamado com o bean de escopo singleton, mas não com o protótipo, porque

O Spring não gerencia o ciclo de vida completo de um protótipo de bean: o contêiner instancia, configura, decora e monta um objeto de protótipo, entrega-o ao cliente e não tem mais conhecimento dessa instância do protótipo. Para liberar recursos, tente implementar um processador pós-bean customizado.

Ao contrário dos grãos singleton, em que o contêiner de mola gerencia o ciclo de vida completo

Você pode dar uma olhada neste tutorial básico para diferenças entre diferentes contextos

Consulte a documentação

43
Manish Singh

Este é o comportamento esperado. Não há como o Spring saber quando você terminou de usar um bean de escopo de protótipo; portanto, a destruição de feijão não é gerenciada pelo Spring para beans com escopo de protótipo. A partir da documentação:

Embora os métodos de retorno de chamada do ciclo de vida de inicialização sejam chamados em todos os objetos, independentemente do escopo, no caso de protótipos, os retornos de chamada configurados do ciclo de vida de destruição não são chamados.

Veja documentação da Spring para obter mais informações.

Com relação a ApplicationContexts, você pode escolher o que melhor se adequa ao seu aplicativo. Depende se você deseja usar a configuração XML ou do bean de anotação e se está executando ou não em um contêiner de servlet, por exemplo. ApplicationContext em si é a interface na raiz da hierarquia de tipos.

2
hertzsprung

Um bean singleton significa que há exatamente uma instância desse bean no contexto do aplicativo. Isso significa que se você fizer algo assim:

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

Você verá "Minha mensagem" na saída do console duas vezes.

Para protótipos de beans sempre que você tentar obter um desses no contexto do aplicativo, você obterá uma nova instância; portanto, se você executar o código acima novamente, a segunda saída do console será "nula".

Como não é necessário que o contêiner chame um método de destruição para um bean protótipo, isso não ocorre e o comportamento está correto.

A diferença entre as classes mencionadas é que elas são uma interface, uma classe abstrata e uma classe concreta, respectivamente, para entender melhor esses conceitos, sugiro ler a documentação oficial do Oracle para Java aqui - Oracle Java Tutoriais .

2
Can Yegane

seu aplicativo pode solicitar novas instâncias de protótipo de beans a cada 10 milissegundos, fazer algo com o bean e deixá-lo sair do escopo. Se o Spring tivesse que destruí-los () quando o aplicativo fosse desligado, ele teria que manter uma referência a cada protótipo de bean criado, impedindo que eles fossem coletados de lixo e causando um vazamento de memória.

2
Vishwanath Sharma

Eu também tentei obter um evento de destruição do bean cujo escopo é "protótipo". Então, eu li todas as respostas acima e tento pelas respostas deles. Como resultado, entendo que não há como detectar uma destruição, mesmo do protótipo de bean.

Embora os métodos de retorno de chamada do ciclo de vida de inicialização sejam chamados em todos os objetos, independentemente do escopo, no caso de protótipos, os retornos de chamada do ciclo de vida de destruição configurados não são chamados.

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

0
Liu Zhe