学习 `@PreDestroy`:Java EE/Jakarta EE 生命周期回调

学习 `@PreDestroy`:Java EE/Jakarta EE 生命周期回调

  • 前言
    • 1. 什么是 `@PreDestroy`?
    • 2. `@PreDestroy` 的用途
    • 3. 使用 `@PreDestroy` 的条件
    • 4. 代码示例
      • 运行结果:
    • 5. `@PreDestroy` 的调用时机
    • 6. 注意事项
    • 7. 实际应用场景
      • 场景 1:数据库连接管理
      • 场景 2:文件资源释放
    • 8. 总结


前言

在 Java EE(Enterprise Edition)和 Jakarta EE 中,@PreDestroy 是一个非常重要的注解,用于管理对象的生命周期。它允许开发者在对象被容器销毁之前执行一些清理操作,比如释放资源、关闭连接等。本文将详细介绍 @PreDestroy 的用法、适用场景以及注意事项,并通过示例帮助大家更好地理解。


1. 什么是 @PreDestroy

@PreDestroy 是 Java EE/Jakarta EE 提供的一个注解,用于标记一个方法,该方法会在对象被容器销毁之前自动调用。它是对象生命周期回调的一部分,通常与 @PostConstruct 配合使用。

  • @PostConstruct:在对象创建并依赖注入完成后调用。
  • @PreDestroy:在对象被销毁之前调用。

2. @PreDestroy 的用途

@PreDestroy 主要用于执行一些清理工作,例如:

  • 关闭数据库连接。
  • 释放文件或网络资源。
  • 清理缓存或临时数据。
  • 注销监听器或回调。

这些操作可以确保资源被正确释放,避免内存泄漏或其他资源浪费问题。


3. 使用 @PreDestroy 的条件

要正确使用 @PreDestroy,需要满足以下条件:

  1. 方法签名
    • 方法必须没有参数。
    • 方法必须返回 void
    • 方法不能抛出受检异常(checked exceptions)。
  2. 托管对象
    • @PreDestroy 只能用于由容器管理的对象,比如 EJB、CDI Bean、Servlet 等。
    • 如果对象是原型作用域(prototype scope),@PreDestroy 不会被调用。

4. 代码示例

以下是一个简单的示例,展示了如何在 CDI Bean 中使用 @PreDestroy

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;@ApplicationScoped
public class ResourceManager {// 模拟资源初始化@PostConstructpublic void init() {System.out.println("资源初始化完成...");}// 业务方法public void doWork() {System.out.println("正在执行任务...");}// 清理资源@PreDestroypublic void cleanup() {System.out.println("正在清理资源...");// 这里可以关闭数据库连接、释放文件资源等}
}

运行结果:

  1. 当容器启动并创建 ResourceManager 实例时,init() 方法会被调用,输出:“资源初始化完成…”。
  2. 当调用 doWork() 方法时,输出:“正在执行任务…”。
  3. 当容器关闭或 Bean 被销毁时,cleanup() 方法会被调用,输出:“正在清理资源…”。

5. @PreDestroy 的调用时机

@PreDestroy 方法会在以下情况下被调用:

  • 应用程序关闭时:当应用服务器或容器关闭时,所有托管对象的 @PreDestroy 方法都会被调用。
  • 作用域结束时:对于具有特定作用域的 Bean(如 @RequestScoped@SessionScoped),当作用域结束时,@PreDestroy 方法会被调用。
  • 容器决定销毁对象时:当容器不再需要某个对象时(例如,对象超出作用域或容器资源不足),@PreDestroy 方法会被调用。

6. 注意事项

  1. 原型作用域的 Bean

    • 如果 Bean 是原型作用域(prototype scope),@PreDestroy 不会被调用,因为容器不管理原型 Bean 的生命周期。
  2. 异常处理

    • @PreDestroy 方法不能抛出受检异常,否则可能会导致容器无法正常销毁对象。
  3. 与 Spring 的兼容性

    • 在 Spring 框架中,@PreDestroy 的功能与 Java EE/Jakarta EE 中的一致。Spring 还提供了其他方式来实现类似功能,比如实现 DisposableBean 接口或在 XML 配置中指定 destroy-method

7. 实际应用场景

场景 1:数据库连接管理

在数据库操作类中,可以使用 @PreDestroy 来确保数据库连接被正确关闭。

@ApplicationScoped
public class DatabaseService {private Connection connection;@PostConstructpublic void init() {// 初始化数据库连接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");}@PreDestroypublic void close() {if (connection != null) {try {connection.close();System.out.println("数据库连接已关闭。");} catch (SQLException e) {e.printStackTrace();}}}
}

场景 2:文件资源释放

在文件操作类中,可以使用 @PreDestroy 来确保文件流被关闭。

@ApplicationScoped
public class FileService {private FileInputStream fileInputStream;@PostConstructpublic void init() {try {fileInputStream = new FileInputStream("data.txt");} catch (FileNotFoundException e) {e.printStackTrace();}}@PreDestroypublic void cleanup() {if (fileInputStream != null) {try {fileInputStream.close();System.out.println("文件流已关闭。");} catch (IOException e) {e.printStackTrace();}}}
}

8. 总结

@PreDestroy 是 Java EE/Jakarta EE 中非常重要的生命周期回调注解,用于在对象销毁之前执行清理操作。通过合理使用 @PreDestroy,可以确保资源被正确释放,避免内存泄漏和资源浪费。在实际开发中,@PreDestroy 通常与 @PostConstruct 配合使用,分别用于初始化和清理工作。

希望本文能帮助你更好地理解和使用 @PreDestroy!如果有任何问题,欢迎留言讨论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/21321.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JUC并发—8.并发安全集合一

大纲 1.JDK 1.7的HashMap的死循环与数据丢失 2.ConcurrentHashMap的并发安全 3.ConcurrentHashMap的设计介绍 4.ConcurrentHashMap的put操作流程 5.ConcurrentHashMap的Node数组初始化 6.ConcurrentHashMap对Hash冲突的处理 7.ConcurrentHashMap的并发扩容机制 8.Concu…

Cython学习笔记1:利用Cython加速Python运行速度

Cython学习笔记1:利用Cython加速Python运行速度 CythonCython 的核心特点:利用Cython加速Python运行速度1. Cython加速Python运行速度原理2. 不使用Cython3. 使用Cython加速(1)使用pip安装 cython 和 setuptools 库(2&…

DApp 开发入门指南

DApp 开发入门指南 🔨 1. DApp 基础概念 1.1 什么是 DApp? 去中心化应用(DApp)是基于区块链的应用程序,特点是: 后端运行在区块链网络前端可以是任何框架使用智能合约处理业务逻辑数据存储在区块链上 1…

基于Spring Security 6的OAuth2 系列之二十 - 高级特性--令牌交换(Token Exchange)

之所以想写这一系列,是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器,但当时基于spring-boot 2.3.x,其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0,结果一看Spring Security也升级…

瑞芯微RV1126部署YOLOv8全流程:环境搭建、pt-onnx-rknn模型转换、C++推理代码、错误解决、优化、交叉编译第三方库

目录 1 环境搭建 2 交叉编译opencv 3 模型训练 4 模型转换 4.1 pt模型转onnx模型 4.2 onnx模型转rknn模型 4.2.1 安装rknn-toolkit 4.2.2 onn转成rknn模型 5 升级npu驱动 6 C++推理源码demo 6.1 原版demo 6.2 增加opencv读取图片的代码 7 交叉编译x264 ffmepg和op…

【开源】编译器,在线操作

目录 1. 思绪思维导图:simple mind map2. Markdown:md-editor-v33. 文档:wangEditor4. 电子表格:Luckysheet5. 幻灯片:PPTist6. 白板:excalidraw7. 流程图:drawio 1. 思绪思维导图:…

跳表(Skip List)详解

一、什么是跳表? 跳表是一种基于有序链表的高效数据结构,通过建立多级索引实现快速查询。它在平均情况下支持O(log n)时间复杂度的搜索、插入和删除操作,性能接近平衡树,但实现更为简单。 二、核心原理 1. 层级结构 底层为完整…

【Quest开发】全身跟踪

软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72 硬件:Meta Quest3 最终效果:能像meta的操作室沉浸场景一样根据头盔移动来推断用户姿势,实现走路、蹲下、手势匹配等功能 需要借助UnityMovement这个包 GitHub …

25年2月通信基础知识补充:多普勒频移与多普勒扩展、3GPP TDL信道模型

看文献过程中不断发现有太多不懂的基础知识,故长期更新这类blog不断补充在这过程中学到的知识。由于这些内容与我的研究方向并不一定强相关,故记录不会很深入请见谅。 【通信基础知识补充7】25年2月通信基础知识补充1 一、多普勒频移与多普勒扩展傻傻分不…

栈,优先级队列,map,set

文章目录 栈题目解析代码 优先级队列题解代码 map题解代码 set题解代码 栈 题目解析 1.先把元素push进栈中&#xff0c;如果栈非空并且栈中的元素按顺序和k相等就出栈&#xff0c;直到栈为空或者k ! sk.top() 代码 #include<iostream> #include<stack> #include&l…

Linux探秘坊-------4.进度条小程序

1.缓冲区 #include <stdio.h> int main() {printf("hello bite!");sleep(2);return 0; }执行此代码后&#xff0c;会 先停顿两秒&#xff0c;再打印出hello bite&#xff0c;但是明明打印在sleep前面&#xff0c;为什么会后打印呢&#xff1f; 因为&#xff…

Redis的预备知识

1.Redis的基本全局命令 Redis有多种数据结构&#xff0c;但它们都是键值对的&#xff0c;对于与键来说有一些通用的命令 1.1 KEYS 返回所有满足样式&#xff08;pattern&#xff09;的key 假定当前具有以下value值&#xff1a;hllo&#xff0c;hello&#xff0c;hallo&…

量子计算的威胁,以及企业可以采取的措施

当谷歌、IBM、Honeywell和微软等科技巨头纷纷投身量子计算领域时&#xff0c;一场技术军备竞赛已然拉开帷幕。 量子计算虽能为全球数字经济带来巨大价值&#xff0c;但也有可能对相互关联的系统、设备和数据造成损害。这一潜在影响在全球网络安全领域引起了强烈关注。也正因如…

nlp|微调大语言模型初探索(3),qlora微调deepseek记录

前言 上篇文章记录了使用lora微调llama-1b,微调成功,但是微调llama-8b显存爆炸,这次尝试使用qlora来尝试微调参数体量更大的大语言模型,看看64G显存的极限在哪里。 1.Why QLora? QLoRA 在模型加载阶段通过 4-bit 量化大幅减少了模型权重的显存占用。QLoRA 通过 反量化到 …

【设计模式】【创建型模式】工厂方法模式(Factory Methods)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…

DeepSeek模型快速部署教程-搭建自己的DeepSeek

前言&#xff1a;在人工智能技术飞速发展的今天&#xff0c;深度学习模型已成为推动各行各业智能化转型的核心驱动力。DeepSeek 作为一款领先的 AI 模型&#xff0c;凭借其高效的性能和灵活的部署方式&#xff0c;受到了广泛关注。无论是自然语言处理、图像识别&#xff0c;还是…

Deepseek 与 ChatGPT:AI 浪潮中的双子星较量

引言 在人工智能飞速发展的当下&#xff0c;AI 语言模型成为了人们关注的焦点。Deepseek 与 ChatGPT 作为其中的佼佼者&#xff0c;各自展现出独特的魅力&#xff0c;引领着 AI 技术的发展潮流。今天&#xff0c;就让我们深入探讨这两款模型&#xff0c;看看它们在 AI 领域中是…

QT事件循环

文章目录 主事件循环事件循环事件调度器事件处理投递事件发送事件 事件循环的嵌套线程的事件循环deleteLater与事件循环QEventLoop类QEventLoop应用等待一段时间同步操作模拟模态对话框 参考 本文主要对QT中的事件循环做简单介绍和使用 Qt作为一个跨平台的UI框架&#xff0c;其…

解决DeepSeek服务器繁忙问题的实用指南

目录 简述 1. 关于服务器繁忙 1.1 服务器负载与资源限制 1.2 会话管理与连接机制 1.3 客户端配置与网络问题 2. 关于DeepSeek服务的备用选项 2.1 纳米AI搜索 2.2 硅基流动 2.3 秘塔AI搜索 2.4 字节跳动火山引擎 2.5 百度云千帆 2.6 英伟达NIM 2.7 Groq 2.8 Firew…

进程等待和进程程序替换

进程控制 进程等待进程程序替换 进程等待 如果子进程没有退出 而父进程在进行执行waitpid进行等待&#xff0c;阻塞等待&#xff0c; 进程阻塞了 在等待某种条件发生&#xff08;子进程退出&#xff09; 进程程序替换 1 #include <stdio.h>2 #include <unistd.h>3…