📜  Java Spring 中的 Bean 生命周期

📅  最后修改于: 2022-05-13 01:55:28.642000             🧑  作者: Mango

Java Spring 中的 Bean 生命周期

先决条件: Spring框架简介

任何对象的生命周期意味着它何时以及如何诞生、它在其整个生命周期中的行为方式以及它何时以及如何死亡。类似地,bean 生命周期指的是 bean 何时以及如何被实例化,在它存在之前它执行什么操作,以及它何时以及如何被销毁。在本文中,我们将讨论 bean 的生命周期。

Bean 生命周期由 spring 容器管理。然后,当我们运行程序时,首先启动了 spring 容器。之后,容器根据请求创建 bean 的实例,然后注入依赖项。最后,当 spring 容器关闭时,bean 被销毁。因此,如果我们想在 bean 实例化和关闭 spring 容器之后执行一些代码,那么我们可以在自定义init()方法和destroy()方法中编写该代码。

下图显示了 bean 生命周期的处理流程。

Bean 生命周期流程

注意:我们可以选择自定义方法名称而不是init()destroy() 。在这里,我们将使用 init() 方法在 spring 容器启动并实例化 bean 时执行其所有代码,并使用 destroy() 方法在关闭容器时执行其所有代码。

实现bean生命周期的方法
Spring 提供了三种方式来实现 bean 的生命周期。为了理解这三种方式,我们举个例子。在这个例子中,我们将为我们的 bean (HelloWorld.java) 编写并激活 init() 和Java() 方法,以在 Spring 容器的启动和关闭时打印一些消息。因此,实现这一点的三种方法是:

1. 通过 XML:在这种方法中,为了对 bean 使用自定义的 init() 和 destroy() 方法,我们必须在定义 bean 时在 Spring XML 配置文件中注册这两个方法。因此,遵循以下步骤:

  • 首先,我们需要创建一个 bean HelloWorld。在这种情况下使用Java并在类中编写 init() 和 destroy() 方法。
Java
// Java program to create a bean
// in the spring framework
package beans;
 
public class HelloWorld {
 
    // This method executes
    // automatically as the bean
    // is instantiated
    public void init() throws Exception
    {
        System.out.println(
            "Bean HelloWorld has been "
            + "instantiated and I'm "
            + "the init() method");
    }
 
    // This method executes
    // when the spring container
    // is closed
    public void destroy() throws Exception
    {
        System.out.println(
            "Container has been closed "
            + "and I'm the destroy() method");
    }
}


XML

             

    
     


Java
// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into the spring container and
        // it will create the instance of
        // the bean as it loads into container
 
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}


Java
// Java program to create a bean
// in the spring framework
package beans;
 
import org.springframework
    .beans.factory.DisposableBean;
 
import org.springframework
    .beans.factory.InitializingBean;
 
// HelloWorld class which implements the
// interfaces
public class HelloWorld
    implements InitializingBean,
 DisposableBean {
 
    @Override
    // It is the init() method
    // of our bean and it gets
    // invoked on bean instantiation
    public void afterPropertiesSet()
throws Exception
    {
        System.out.println(
            "Bean HelloWorld has been "
            + "instantiated and I'm the "
            + "init() method");
    }
 
    @Override
    // This method is invoked
    // just after the container
    // is closed
    public void destroy() throws Exception
    {
        System.out.println(
            "Container has been closed "
            + "and I'm the destroy() method");
    }
}


XML

             

    
     


Java
// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into the spring container and
        // it will create the instance of the bean
        // as it loads into container
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}


Java
// Java program to create a bean
// in the spring framework
package beans;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
// HelloWorld class
public class HelloWorld {
 
    // Annotate this method to execute it
    // automatically as the bean is
    // instantiated
    @PostConstruct
    public void init() throws Exception
    {
        System.out.println(
            "Bean HelloWorld has been "
            + "instantiated and I'm the "
            + "init() method");
    }
 
    // Annotate this method to execute it
    // when Spring container is closed
    @PreDestroy
    public void destroy() throws Exception
    {
        System.out.println(
            "Container has been closed "
            + "and I'm the destroy() method");
    }
}


HTML

             

 
    
 
    
 
    
    
     


Java
// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into Spring container and
        // it will create the instance of the
        // bean as it loads into container
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the Spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}


  • 现在,我们需要配置 spring XML 文件spring.xml并需要在其中注册 init() 和 destroy() 方法。

XML


             

    
     

  • 最后,我们需要创建一个驱动类来运行这个 bean。

Java

// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into the spring container and
        // it will create the instance of
        // the bean as it loads into container
 
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}

输出:

2. 通过程序化方法:为了给创建的 bean 提供在 spring 容器启动时调用自定义init()方法和在关闭容器时调用自定义destroy()方法的工具,我们需要用两个实现我们的 bean接口即InitializingBeanDisposableBean并且必须覆盖afterPropertiesSet()destroy()方法。 afterPropertiesSet()方法在容器启动并实例化 bean 时调用,而destroy()方法在容器关闭后调用。

注意:要调用 destroy 方法,我们必须调用 ConfigurableApplicationContext 的close()方法。

因此,遵循以下步骤:

  • 首先,我们需要创建一个 bean HelloWorld。在这种情况下, Java通过实现 InitializingBean、DisposableBean 并覆盖 afterPropertiesSet() 和 destroy() 方法。

Java

// Java program to create a bean
// in the spring framework
package beans;
 
import org.springframework
    .beans.factory.DisposableBean;
 
import org.springframework
    .beans.factory.InitializingBean;
 
// HelloWorld class which implements the
// interfaces
public class HelloWorld
    implements InitializingBean,
 DisposableBean {
 
    @Override
    // It is the init() method
    // of our bean and it gets
    // invoked on bean instantiation
    public void afterPropertiesSet()
throws Exception
    {
        System.out.println(
            "Bean HelloWorld has been "
            + "instantiated and I'm the "
            + "init() method");
    }
 
    @Override
    // This method is invoked
    // just after the container
    // is closed
    public void destroy() throws Exception
    {
        System.out.println(
            "Container has been closed "
            + "and I'm the destroy() method");
    }
}
  • 现在,我们需要配置 spring XML 文件spring.xml并定义 bean。

XML


             

    
     

  • 最后,我们需要创建一个驱动类来运行这个 bean。

Java

// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into the spring container and
        // it will create the instance of the bean
        // as it loads into container
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}

输出:

3.使用注解:为创建的bean提供在spring容器启动时调用自定义init()方法和关闭容器时调用自定义destroy()方法的便利,我们需要用@注解init()方法PostConstruct注释和@PreDestroy注释的destroy()方法。
注意:要调用destroy()方法,我们必须调用ConfigurableApplicationContext 的close()方法。

因此,遵循以下步骤:

  • 首先,我们需要创建一个 bean HelloWorld。在这种情况下使用Java并使用 @PostConstruct 注释自定义 init() 方法,并使用 @PreDestroy 注释destroy() 方法。

Java

// Java program to create a bean
// in the spring framework
package beans;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
// HelloWorld class
public class HelloWorld {
 
    // Annotate this method to execute it
    // automatically as the bean is
    // instantiated
    @PostConstruct
    public void init() throws Exception
    {
        System.out.println(
            "Bean HelloWorld has been "
            + "instantiated and I'm the "
            + "init() method");
    }
 
    // Annotate this method to execute it
    // when Spring container is closed
    @PreDestroy
    public void destroy() throws Exception
    {
        System.out.println(
            "Container has been closed "
            + "and I'm the destroy() method");
    }
}
  • 现在,我们需要配置 spring XML 文件 spring.xml 并定义 bean。

HTML


             

 
    
 
    
 
    
    
     

  • 最后,我们需要创建一个驱动类来运行这个 bean。

Java

// Java program to call the
// bean initialized above
 
package test;
 
import org.springframework
    .context
    .ConfigurableApplicationContext;
 
import org.springframework
    .context.support
    .ClassPathXmlApplicationContext;
 
import beans.HelloWorld;
 
// Driver class
public class Client {
 
    public static void main(String[] args)
        throws Exception
    {
 
        // Loading the Spring XML configuration
        // file into Spring container and
        // it will create the instance of the
        // bean as it loads into container
        ConfigurableApplicationContext cap
            = new ClassPathXmlApplicationContext(
                "resources/spring.xml");
 
        // It will close the Spring container
        // and as a result invokes the
        // destroy() method
        cap.close();
    }
}

输出: