JAVA生命周期注解和资源释放

构造方法 → @PostConstruct 方法 → 业务逻辑 → @PreDestroy 方法 → 对象销毁

@PreDestroy 

生命周期管理的注解,它属于 Java 规范(JSR-250)中定义的注解,@PreDestroy 依赖容器的支持(如 Spring、Java EE 容器),如果对象是通过 new 手动创建的(非容器托管),注解不会生效

  1. 作用时机
    被 @PreDestroy 标记的方法,会在对象即将被容器(如 Spring 容器、EJB 容器)销毁之前调用。具体时机因容器而异:

    • 在 Spring 中,当单例 bean 被容器销毁(如容器关闭)时触发。
    • 在 Java EE 中,当托管对象(如 EJB、CDI bean)被容器移除时触发。
  2. 方法要求

    • 注解只能标记在非静态方法上。
    • 方法可以有任意访问修饰符(publicprotectedprivate)。
    • 方法不能有参数,且返回值必须为 void
    • 方法不能抛出受检异常(checked exception),但可以抛出非受检异常(unchecked exception)。
  3. 依赖关系
    如果多个 bean 之间存在依赖关系,容器会先调用依赖对象的 @PreDestroy 方法,再调用当前对象的 @PreDestroy 方法,确保资源释放的顺序正确。

@PostConstruct

JAVA类静态资源 需要手动释放吗,JVM停止时会自动释放这些资源吗

JVM 停止(进程终止)时,操作系统会回收进程占用的系统级资源(如内存、文件描述符、网络端口等),但应用级资源(如逻辑连接、线程池状态等)需要手动处理,否则可能导致中间状态异常(如未完成的任务、数据不一致)。

线程池 / 线程ExecutorService调用 shutdown() 或 shutdownNow()
数据库连接池HikariCPDruid调用 close() 关闭连接池
网络连接SocketHttpClient调用 close() 关闭连接
文件流FileInputStream调用 close() 或使用 try-with-resources
分布式资源分布式锁、缓存连接释放锁、关闭缓存客户端

如何正确手动释放静态资源?

根据运行环境,可通过以下方式释放静态资源:

  1. 通用场景(非容器环境)
    注册 JVM 关闭钩子(Shutdown Hook),在 JVM 终止前执行释放逻辑:

    public class StaticResourceHolder {
        private static final ExecutorService executor = Executors.newFixedThreadPool(5);
        
        static {
            // 注册关闭钩子
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                System.out.println("释放静态线程池...");
                executor.shutdown(); // 优雅关闭线程池
            }));
        }
    }
    
  2. Spring 容器环境
    利用 Spring 的生命周期回调(如 @PreDestroy),在容器关闭时释放:

    @Component
    public class StaticResourceManager {
        private static final HikariDataSource dataSource = new HikariDataSource();
        
        // Spring 容器关闭时触发
        @PreDestroy
        public void closeDataSource() {
            dataSource.close(); // 关闭数据库连接池
        }
    }
    
  3. 手动调用释放方法
    在程序逻辑结束处(如 main 方法末尾)显式调用释放方法:

    public class App {
        private static final SomeResource resource = new SomeResource();
        
        public static void main(String[] args) {
            try {
                // 业务逻辑
            } finally {
                resource.close(); // 手动释放
            }
        }
    }

如果直接通过 kill 命令(如 kill -9)强制终止 JVM 进程,所有资源释放逻辑(如 @PreDestroy 方法、JVM 关闭钩子 Shutdown Hook 等)都不会被执行。

kill -15(默认信号 SIGTERM):属于 “温和终止”,会通知 JVM 进程准备退出。此时 JVM 会触发关闭钩子(Shutdown Hook)、@PreDestroy 等资源释放逻辑,然后正常退出

kill -9(信号 SIGKILL):属于 “强制终止”,操作系统会直接终止进程,不会给 JVM 任何执行清理逻辑的机会,所有资源释放代码都不会运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值