Java Spring 中的 Bean 生命周期
先决条件: Spring框架简介
任何对象的生命周期意味着它何时以及如何诞生、它在其整个生命周期中的行为方式以及它何时以及如何死亡。类似地,bean 生命周期指的是 bean 何时以及如何被实例化,在它存在之前它执行什么操作,以及它何时以及如何被销毁。在本文中,我们将讨论 bean 的生命周期。
Bean 生命周期由 spring 容器管理。然后,当我们运行程序时,首先启动了 spring 容器。之后,容器根据请求创建 bean 的实例,然后注入依赖项。最后,当 spring 容器关闭时,bean 被销毁。因此,如果我们想在 bean 实例化和关闭 spring 容器之后执行一些代码,那么我们可以在自定义init()方法和destroy()方法中编写该代码。
下图显示了 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();
}
}
输出:
Bean HelloWorld has been instantiated and I’m the init() method
Container has been closed and I’m the destroy() method
2. 通过程序化方法:为了给创建的 bean 提供在 spring 容器启动时调用自定义init()方法和在关闭容器时调用自定义destroy()方法的工具,我们需要用两个实现我们的 bean接口即InitializingBean , DisposableBean并且必须覆盖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();
}
}
输出:
Bean HelloWorld has been instantiated and I’m the init() method
Container has been closed and I’m the destroy() method
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();
}
}
输出:
Bean HelloWorld has been instantiated and I’m the init() method
Container has been closed and I’m the destroy() method