• Spring注解驱动之@PostConstruct和PreDestroy注解


    概述

    在之前的文章中,我们介绍了如何使用@Bean注解指定初始化和销毁的方法,也介绍了使用InitializingBean和DisposableBean来处理bean的初始化和销毁。除此之外,在JDK中还提供了两个注解能够在bean创建完成并且属性赋值完成之后执行一些初始化工作和在容器销毁bean之前通知我们进行一些清理工作。

    @PostConstruct和@PreDestroy注解

    @PostConstruct注解

    @PostConstruct注解好多人以为是Spring提供的,其实它是Java自己的注解,是JSR-250规范里面定义的一个注解。我们来看下@PostConstruct注解的源码。

    package javax.annotation;
    
    import java.lang.annotation.*;
    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.*;
    
    @Documented
    @Retention (RUNTIME)
    @Target(METHOD)
    public @interface PostConstruct {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    从源码可以看出,@PostConstruct注解是Java中的注解,并不是Spring提供的注解。

    @PostConstruct注解被用来修饰一个非静态的void()方法。被@PostConstruct注解修饰的方法会在服务器加载Servlet的时候运行,并且之后被服务器执行一次。被@PostConstruct注解修饰的方法通常在构造函数之后,init()方法之前。

    通常我们是会在Spring框架中使用到@PostConstruct注解的,该注解的方法在整个bean初始化中的执行顺序如下:

    Construct(构造方法)-> @Autowired(依赖注入)-> @PostConstruct(注释的方法)
    
    • 1

    @PreDestroy注解

    @PreDestroy注解同样是Java提供的,它也是JSR-250规范里面定义的一个注解。看它下面的源码。

    package javax.annotation;
    
    import java.lang.annotation.*;
    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.*;
    
    @Documented
    @Retention (RUNTIME)
    @Target(METHOD)
    public @interface PreDestroy {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    被@PreDestroy注解修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy注解修饰的方法会在destroy()方法之后,Servlet被彻底卸载之前执行。执行顺序如下所示:

    调用destroy()方法 -> @PreDestroy(注解的方法) -> destroy()方法 -> bean销毁
    
    • 1

    小结

    @PostConstruct和@PreDestroy是Java规范JSR-250引入的注解,定义了对象的创建和销毁工作,同一期规范中还有@Resource注解,Spring也支持了这些注解。

    案例

    对@PostConstruct注解和@PreDestroy注解有了简单的了解之后,接下来,我们就写一个简单的程序来加深对这两个注解的理解。

    首先,我们创建一个Dog类,如下所示,注意在该类上标注了一个@Component注解。

    package com.meimeixia.bean;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class Dog {
    
    	public Dog() {
    		System.out.println("dog constructor...");
    	}
    	
    	// 在对象创建完成并且属性赋值完成之后调用
    	@PostConstruct
    	public void init() {
    		System.out.println("dog...@PostConstruct...");
    	}
    	
    	// 在容器销毁(移除)对象之前调用
    	@PreDestroy
    	public void destory() {
    		System.out.println("dog...@PreDestroy...");
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    可以看到,在以上Dog类中,我们提供了构造方法、init()方法以及destroy()方法,并且还使用了@PostConstruct注解和@PreDestroy注解来分别标注init()方法和destroy()方法。

    然后,在MainConfigOfLifeCycle配置类中通过包扫描的方式将以上类注入到Spring容器中。

    package com.meimeixia.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    
    import com.meimeixia.bean.Car;
    
    @ComponentScan("com.meimeixia.bean")
    @Configuration
    public class MainConfigOfLifeCycle {
    
    	@Scope("prototype")
    	@Bean(initMethod="init", destroyMethod="destroy")
    	public Car car() {
    		return new Car();
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    接着,运行IOCTest_LifeCycle类中的test01()方法,输出的结果信息如下所示。
    在这里插入图片描述
    从输出的结果信息中可以看出,被@PostConstruct注解修饰的方法是在bean创建完成并且属性赋值完成之后才执行的,而被@PreDestroy注解修饰的方法是在容器销毁bean之前执行的,通常是进行一些清理工作。

    参考

    Spring注解驱动开发第14讲——你了解@PostConstruct注解和@PreDestroy注解吗?

  • 相关阅读:
    OpenCV图像处理——图像梯度
    Jenkins部署springboot项目至远程服务器
    玩转SQLite7:基本语法与数据类型
    ubuntu22.04安装Kubernetes1.25.0(k8s1.25.0)高可用集群
    ASP.NET Core 6 从入门到企业级实战开发应用技术汇总
    前端解决跨域请求
    vim相关介绍(二)
    MSE实现全链路灰度实践
    【总结】maven 打包刷新下载依赖卡死
    学习编程的目的
  • 原文地址:https://blog.csdn.net/tianzhonghaoqing/article/details/126689583