📜  Spring – @PostConstruct 和 @PreDestroy 注解与示例

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

Spring – @PostConstruct 和 @PreDestroy 注解与示例

Spring 是最流行的Java EE 框架之一。它是一个开源轻量级框架,允许Java EE 7 开发人员构建简单、可靠且可扩展的企业应用程序。该框架主要侧重于提供各种方法来帮助您管理业务对象。与Java数据库连接 (JDBC)、JavaServer Pages (JSP) 和Java Servlet 等经典Java框架和应用程序编程接口 (API) 相比,它使 Web 应用程序的开发更加容易。该框架使用各种新技术,如面向方面编程 (AOP)、普通Java对象 (POJO) 和依赖注入 (DI) 来开发企业应用程序。现在谈论 Spring Annotation

所以发生的情况是,每当我们使用依赖注入配置 Spring Beans 时,有时我们希望确保在 bean 开始为客户端请求提供服务之前一切都正确初始化。同样,当 context 被销毁时,我们可能不得不关闭 spring bean 使用的一些资源。

Spring @PostConstruct 注解

所以一般来说,每当我们在 Spring Bean 中使用 @PostConstruct 注解来注解一个方法时,它都会在 Spring Bean 初始化之后执行。我们只能有一个使用@PostConstruct 注释的方法。此注解是 Common Annotations API 的一部分,也是 JDK模块 javax.annotation-api的一部分。

Spring @PreDestroy 注解

当我们使用 PreDestroy 注解对 Spring Bean 方法进行注解时,它会在 bean 实例从上下文中移除时被调用。请记住,如果您的 spring bean 范围是“原型”,那么它不会完全由 spring 容器管理,并且不会调用 PreDestroy 方法。如果有一个名为 shutdown 或 close 的方法,那么当 bean 被销毁时,spring 容器将尝试自动将它们配置为回调方法。

在项目中添加@PostConstruct 和@PreDestroy 注解

使用Java 9+ 的开发人员,@PostConstruct 和 @PreDestroy 注释都是Java EE 的一部分。由于Java EE 在Java 9 中已被弃用并在Java 11 中被删除,我们必须添加一个额外的依赖项才能使用这些注解:

A.如果您使用的是 Maven


   javax.annotation
   javax.annotation-api
   1.3.2

B.如果手动添加jar

访问链接并在文件列中,您将看到 pom 和 jar。单击 jar,您的 jar 将被下载。通过配置构建将其作为外部 jar 添加到类路径中。您可以参考这篇文章将外部 JAR 文件添加到 IntelliJ IDEA 项目或参考这篇文章将外部 JAR 文件添加到 Eclipse 项目。

实现:我们将通过简单地创建一个 Spring JDBC 项目来解释 @PostConstruct 和 @PreDestroy 注解。所以我们先创建一个 Spring JDBC 项目。

第 1 步:在您首选的 IDE(IntelliJ IDEA 或 Eclipse)中创建一个简单的Java项目。你可以参考这些文章:

  • 在 IntelliJ IDEA 中创建第一个Java应用程序
  • 如何为Java安装 Eclipse IDE?

第 2 步:在数据库中创建一些表。在本文中,我们使用了 MySQL 数据库。我们的 MySQL 数据库中已经存在以下数据。

MySQL 数据库中的数据

所以这里的studentdb是我们的模式名, hostelstudentinfo是表名。同样,您可以创建自己的模式和表,并手动将一些数据放入该表中。

第 3 步:转到Java项目并创建一个名为StudentDAO的类,在该类中,我们将创建一个方法selectAllRows()来获取 MySQL 数据库中存在的所有数据。我们还将声明我们的四个最重要的属性,以将我们的Java程序与 MySQL 服务器连接起来。

  • 司机
  • 网址
  • 用户
  • 密码

例子:

Java
// Java Program to Illustrate StudentDAO class
 
// Importing required classes
import java.sql.*;
 
// Class
public class StudentDAO {
 
    // Class data members
    private String driver;
    private String url;
    private String userName;
    private String password;
 
    // Setter methods for
    // Setter Injection
    public void setDriver(String driver)
    {
        // This keyword refers to current instance itself
        this.driver = driver;
    }
 
    // Setter
    public void setUrl(String url) { this.url = url; }
 
    // Setter
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
 
    // Setter
    public void setPassword(String password)
    {
        this.password = password;
    }
 
    // Method
    public void selectAllRows()
        throws ClassNotFoundException, SQLException
    {
        System.out.println("Retrieving all student data..");
 
        // Loading driver using forname() method
        Class.forName(driver);
 
        // Getting a connection
        Connection con = DriverManager.getConnection(
            url, userName, password);
 
        // Executing a query
        Statement stmt = con.createStatement();
 
        ResultSet rs = stmt.executeQuery(
            "SELECT * FROM studentdb.hostelstudentinfo");
 
        // Iterating over till condition holds true
        while (rs.next()) {
            int studentId = rs.getInt(1);
            String studentName = rs.getString(2);
            double hostelFees = rs.getDouble(3);
            String foodType = rs.getString(4);
 
            // Print statement
            System.out.println(studentId + " " + studentName
                               + " " + hostelFees + " "
                               + foodType);
        }
 
        // Closing the connection
        // using close() method
        con.close();
    }
}


XML


 
    
        
        
        
        
    
 


Java
// Java Program to Illustrate Application File
 
// Importing required classes
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
// Application class
public class Main {
 
    // Main driver method
    public static void main(String[] args)
        throws SQLException, ClassNotFoundException
    {
 
        // Implementing Spring IoC
        // using ApplicationContext
        ApplicationContext context
            = new ClassPathXmlApplicationContext(
                "beans.xml");
 
        // Getting the bean studentDAO
        StudentDAO studentDAO = context.getBean(
            "studentDAO", StudentDAO.class);
 
        // Calling the method
        studentDAO.selectAllRows();
    }
}


Java
// Java Program Illustrating Method to Delete Student Record
 
public void deleteStudentRecord(int studentId)
    throws ClassNotFoundException, SQLException
{
    // Display message
    System.out.println("Deleting student data..");
 
    // Loading driver using forName() Method
    Class.forName(driver);
 
    // Getting a connection
    Connection con = DriverManager.getConnection(
        url, userName, password);
 
    // Executing a query
    Statement stmt = con.createStatement();
 
    stmt.executeUpdate(
        "delete from studentdb.hostelstudentinfo where Student_id = "
        + studentId);
    System.out.println("Record Deleted with the ID "
                       + studentId);
 
    // Closing the connections
    // using close() method
    con.close();
}


Java
// Java Program Illustrating Method to Create StudentDB
// Connection
 
// Method
public void createStudentDBConnection()
    throws ClassNotFoundException, SQLException
{
 
    // Loading driver
    Class.forName(driver);
 
    // Getting a connection
    con = DriverManager.getConnection(url, userName,
                                      password);
 
    // Executing a query
    stmt = con.createStatement();
}


Java
// Java Program to Illustrate StudentDAO Class
 
// Importing required classes
import java.sql.*;
 
// Class
public class StudentDAO {
 
    // Class data members
    private String driver;
    private String url;
    private String userName;
    private String password;
 
    // Connection Object
    Connection con;
 
    // Statement Object
    Statement stmt;
 
    // Setter
    public void setDriver(String driver)
    {
        this.driver = driver;
    }
 
    // Setter
    public void setUrl(String url) { this.url = url; }
 
    // Setter
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
 
    // Setter
    public void setPassword(String password)
    {
        this.password = password;
    }
 
    // Creating connection
    public void createStudentDBConnection()
        throws ClassNotFoundException, SQLException
    {
 
        // Loading  driver
        Class.forName(driver);
 
        // Getting a connection
        con = DriverManager.getConnection(url, userName,
                                          password);
 
        // Executing query
        stmt = con.createStatement();
    }
 
    // Method 1
    public void selectAllRows()
        throws ClassNotFoundException, SQLException
    {
        System.out.println("Retrieving all student data..");
 
        // Create connection
        createStudentDBConnection();
 
        ResultSet rs = stmt.executeQuery(
            "SELECT * FROM studentdb.hostelstudentinfo");
 
        while (rs.next()) {
            int studentId = rs.getInt(1);
            String studentName = rs.getString(2);
            double hostelFees = rs.getDouble(3);
            String foodType = rs.getString(4);
 
            System.out.println(studentId + " " + studentName
                               + " " + hostelFees + " "
                               + foodType);
        }
 
        // Closing the connection
        closeConnection()
    }
 
    // Method 2
    public void deleteStudentRecord(int studentId)
        throws ClassNotFoundException, SQLException
    {
        System.out.println("Deleting student data..");
 
        // Create connection
        createStudentDBConnection();
 
        stmt.executeUpdate(
            "delete from studentdb.hostelstudentinfo where Student_id = "
            + studentId);
        System.out.println("Record Deleted with the ID "
                           + studentId);
 
        // Close the connection
        closeConnection();
    }
 
    // Method 3
    // Close the connection
    public void closeConnection() throws SQLException
    {
        con.close();
    }
}


Java
@PostConstruct
public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }


Java
@PostConstruct
public void init() throws SQLException, ClassNotFoundException {
        createStudentDBConnection();
    }
 
public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }


Java
public void closeConnection() throws SQLException {
        con.close();
    }
 
@PreDestroy
public void destroy() throws SQLException {
        closeConnection();
    }


Java
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.sql.*;
 
public class StudentDAO {
 
    private String driver;
    private String url;
    private String userName;
    private String password;
 
    // Connection Object
    Connection con;
 
    // Statement Object
    Statement stmt;
 
    public void setDriver(String driver) {
        this.driver = driver;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public void setUserName(String userName) {
        this.userName = userName;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    @PostConstruct
    public void init() throws SQLException, ClassNotFoundException {
        createStudentDBConnection();
    }
 
    public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }
 
    public void selectAllRows() throws ClassNotFoundException, SQLException {
 
        System.out.println("Retrieving all student data..");
 
        ResultSet rs = stmt.executeQuery("SELECT * FROM studentdb.hostelstudentinfo");
 
        while (rs.next()) {
            int studentId = rs.getInt(1);
            String studentName = rs.getString(2);
            double hostelFees = rs.getDouble(3);
            String foodType = rs.getString(4);
 
            System.out.println(studentId + " " + studentName + " " + hostelFees + " " + foodType);
        }
    }
 
    public void deleteStudentRecord(int studentId) throws ClassNotFoundException, SQLException {
        System.out.println("Delete student data..");
 
        stmt.executeUpdate("delete from studentdb.hostelstudentinfo where Student_id = " + studentId);
        System.out.println("Record Deleted with the ID " + studentId);
    }
 
    public void closeConnection() throws SQLException {
        con.close();
    }
 
    @PreDestroy
    public void destroy() throws SQLException {
        closeConnection();
    }
}


XML


 
    
 
    
        
        
        
        
    
 


Java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import java.sql.SQLException;
 
public class Main {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
       
        // Using ApplicationContext tom implement Spring IoC
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       
        // Get the bean studentDAO
        StudentDAO studentDAO = context.getBean("studentDAO", StudentDAO.class);
       
        // Calling the method
        studentDAO.deleteStudentRecord(2);
        studentDAO.selectAllRows();
    }
}


第 4 步:现在我们必须将外部 JAR 文件添加到 IntelliJ IDEA 项目中。 JAR(Java Archive)是一种包文件格式,通常用于将许多Java类文件和相关的元数据和资源(文本、图像等)聚合到一个文件中,以在Java平台上分发应用程序软件或库。简而言之,JAR 文件是包含 .class 文件、音频文件、图像文件或目录的压缩版本的文件。我们必须将以下外部 jar 文件添加到我们的Java项目中

  • 春天
  • MySQL 连接器

您可以从以下链接下载 jar 文件:

  • 春天:点击这里
  • MySQL 连接器:单击此处

第 5 步:让我们在beans.xml文件中创建 StudentDAO 类的 bean,并通过 setter 注入来注入属性的值。你可以参考这篇文章 Spring – Injecting 字面量 Values By Setter Injection。下面是beans.xml文件的代码。

XML



 
    
        
        
        
        
    
 

第 6 步:创建 Main 类,让我们测试我们的应用程序是否运行良好。下面是Main 的代码。 Java文件。

Java

// Java Program to Illustrate Application File
 
// Importing required classes
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
// Application class
public class Main {
 
    // Main driver method
    public static void main(String[] args)
        throws SQLException, ClassNotFoundException
    {
 
        // Implementing Spring IoC
        // using ApplicationContext
        ApplicationContext context
            = new ClassPathXmlApplicationContext(
                "beans.xml");
 
        // Getting the bean studentDAO
        StudentDAO studentDAO = context.getBean(
            "studentDAO", StudentDAO.class);
 
        // Calling the method
        studentDAO.selectAllRows();
    }
}

输出:可以看到我们已成功从 MySQL 数据库中获取数据。

Retrieving all student data..
1 Asish 300.5 Veg
2 Vicky 245.89 Non Veg
3 Anshul 123.67 Veg

例子

Java

// Java Program Illustrating Method to Delete Student Record
 
public void deleteStudentRecord(int studentId)
    throws ClassNotFoundException, SQLException
{
    // Display message
    System.out.println("Deleting student data..");
 
    // Loading driver using forName() Method
    Class.forName(driver);
 
    // Getting a connection
    Connection con = DriverManager.getConnection(
        url, userName, password);
 
    // Executing a query
    Statement stmt = con.createStatement();
 
    stmt.executeUpdate(
        "delete from studentdb.hostelstudentinfo where Student_id = "
        + studentId);
    System.out.println("Record Deleted with the ID "
                       + studentId);
 
    // Closing the connections
    // using close() method
    con.close();
}

现在您可以看到我们必须一次又一次地编写一些代码行。然后想想如果假设我们要执行 100 种不同的操作,我们必须一次又一次地编写相同的代码。所以我们能做些什么。我们可以在方法中编写通用代码,然后调用该方法。我们可以在名为createStudentDBConnection()的方法中编写类似这样的内容

例子

Java

// Java Program Illustrating Method to Create StudentDB
// Connection
 
// Method
public void createStudentDBConnection()
    throws ClassNotFoundException, SQLException
{
 
    // Loading driver
    Class.forName(driver);
 
    // Getting a connection
    con = DriverManager.getConnection(url, userName,
                                      password);
 
    // Executing a query
    stmt = con.createStatement();
}

同样,我们也可以定义另一种方法来关闭连接。我们可以在名为closeConnection()的方法中编写类似这样的内容

public void closeConnection() throws SQLException 
{
  con.close();
}

我们可以像这样在 selectAllRows() 和 deleteStudentRecord() 中调用这些方法。

例子

Java

// Java Program to Illustrate StudentDAO Class
 
// Importing required classes
import java.sql.*;
 
// Class
public class StudentDAO {
 
    // Class data members
    private String driver;
    private String url;
    private String userName;
    private String password;
 
    // Connection Object
    Connection con;
 
    // Statement Object
    Statement stmt;
 
    // Setter
    public void setDriver(String driver)
    {
        this.driver = driver;
    }
 
    // Setter
    public void setUrl(String url) { this.url = url; }
 
    // Setter
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
 
    // Setter
    public void setPassword(String password)
    {
        this.password = password;
    }
 
    // Creating connection
    public void createStudentDBConnection()
        throws ClassNotFoundException, SQLException
    {
 
        // Loading  driver
        Class.forName(driver);
 
        // Getting a connection
        con = DriverManager.getConnection(url, userName,
                                          password);
 
        // Executing query
        stmt = con.createStatement();
    }
 
    // Method 1
    public void selectAllRows()
        throws ClassNotFoundException, SQLException
    {
        System.out.println("Retrieving all student data..");
 
        // Create connection
        createStudentDBConnection();
 
        ResultSet rs = stmt.executeQuery(
            "SELECT * FROM studentdb.hostelstudentinfo");
 
        while (rs.next()) {
            int studentId = rs.getInt(1);
            String studentName = rs.getString(2);
            double hostelFees = rs.getDouble(3);
            String foodType = rs.getString(4);
 
            System.out.println(studentId + " " + studentName
                               + " " + hostelFees + " "
                               + foodType);
        }
 
        // Closing the connection
        closeConnection()
    }
 
    // Method 2
    public void deleteStudentRecord(int studentId)
        throws ClassNotFoundException, SQLException
    {
        System.out.println("Deleting student data..");
 
        // Create connection
        createStudentDBConnection();
 
        stmt.executeUpdate(
            "delete from studentdb.hostelstudentinfo where Student_id = "
            + studentId);
        System.out.println("Record Deleted with the ID "
                           + studentId);
 
        // Close the connection
        closeConnection();
    }
 
    // Method 3
    // Close the connection
    public void closeConnection() throws SQLException
    {
        con.close();
    }
}

但我们又在做同样的事情。我们在selectAllRows()和 deleteStudentRecord() 方法中一次又一次地调用createStudentDBConnection()closeConnection ()方法。假设我们总共有 100 个这样的实用方法,那么我们必须调用这些方法 100 次。所以我们会告诉我们的 spring 框架,一旦你(spring 框架)创建了 bean,请执行createStudentDBConnection()方法。所以我们要告诉 Spring 框架的方式是添加@PostConstruct注解。总之,我们可以说

所以现在我们可以把@PostConstruct注解 createStudentDBConnection()之前是这样的

Java

@PostConstruct
public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }


介绍 init()

在实际应用程序中, init()方法是随处可见的方法。我们也可以说init()方法是一个标准名称。例如,在这个项目中,我们可以将createStudentDBConnection()方法标记为 init。这里createStudentDBConnection()是我们的 init() 方法。使用@PostConstruct注释方法以将其用作 init() 方法。我们不需要调用 init() 方法,我们的框架会为我们调用它。我们可以将我们的 init() 方法名称作为任何名称。我们可以说它init()或者我们可以说它createStudentDBConnection()xyz() 。所以现在我们可以写同样的东西

Java

@PostConstruct
public void init() throws SQLException, ClassNotFoundException {
        createStudentDBConnection();
    }
 
public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }

为什么是 init()?

  • 您可以在 bean 初始化期间添加自定义代码/逻辑
  • 它可用于设置数据库/套接字/文件等资源。

介绍destroy()

在从容器中删除 bean 之前,将调用 destroy() 方法。现在让我们来看看 closeConnection()方法。我们定义了这个方法来清理未使用的引用。例如在这个项目中的con变量。因此,我们可以通过将任何方法标记为@PreDestroy来将其设为 destroy() 方法。所以现在我们可以编写类似的代码

Java

public void closeConnection() throws SQLException {
        con.close();
    }
 
@PreDestroy
public void destroy() throws SQLException {
        closeConnection();
    }

请注意,我们也可以在 closeConnection() 方法之前使用 @PreDestroy 注解。现在是StudentDAO 的完整代码。 Java类是

Java

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.sql.*;
 
public class StudentDAO {
 
    private String driver;
    private String url;
    private String userName;
    private String password;
 
    // Connection Object
    Connection con;
 
    // Statement Object
    Statement stmt;
 
    public void setDriver(String driver) {
        this.driver = driver;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public void setUserName(String userName) {
        this.userName = userName;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    @PostConstruct
    public void init() throws SQLException, ClassNotFoundException {
        createStudentDBConnection();
    }
 
    public void createStudentDBConnection() throws ClassNotFoundException, SQLException {
        // load driver
        Class.forName(driver);
 
        // get a connection
        con = DriverManager.getConnection(url, userName, password);
 
        // execute query
        stmt = con.createStatement();
    }
 
    public void selectAllRows() throws ClassNotFoundException, SQLException {
 
        System.out.println("Retrieving all student data..");
 
        ResultSet rs = stmt.executeQuery("SELECT * FROM studentdb.hostelstudentinfo");
 
        while (rs.next()) {
            int studentId = rs.getInt(1);
            String studentName = rs.getString(2);
            double hostelFees = rs.getDouble(3);
            String foodType = rs.getString(4);
 
            System.out.println(studentId + " " + studentName + " " + hostelFees + " " + foodType);
        }
    }
 
    public void deleteStudentRecord(int studentId) throws ClassNotFoundException, SQLException {
        System.out.println("Delete student data..");
 
        stmt.executeUpdate("delete from studentdb.hostelstudentinfo where Student_id = " + studentId);
        System.out.println("Record Deleted with the ID " + studentId);
    }
 
    public void closeConnection() throws SQLException {
        con.close();
    }
 
    @PreDestroy
    public void destroy() throws SQLException {
        closeConnection();
    }
}

在运行应用程序之前,请确保您已在beans.xml文件中添加以下行以使用注释

beans.xml文件的完整代码如下所示

XML



 
    
 
    
        
        
        
        
    
 

Main 的完整代码。 Java文件在下面给出

Java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import java.sql.SQLException;
 
public class Main {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
       
        // Using ApplicationContext tom implement Spring IoC
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       
        // Get the bean studentDAO
        StudentDAO studentDAO = context.getBean("studentDAO", StudentDAO.class);
       
        // Calling the method
        studentDAO.deleteStudentRecord(2);
        studentDAO.selectAllRows();
    }
}

输出:

Delete student data..
Record Deleted with the ID 2
Retrieving all student data..
1 Asish 300.5 Veg
3 Anshul 123.67 Veg