简介@PostConstruct & @PreDestroy
被@PostConstruct注解修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的init()方法,被@PostConstruct注解修饰的方法会在构造函数之后,init()方法执行之前执行
被@PreDestroy注解修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法,被@PreDestroy注解修饰的方法会在destroy()方法之后、在Servlet被彻底卸载之前执行
测试 🌰
我们通过一个简单的示🌰来看下这两个注解的作用(想了解更多关于@PostConstruct注解的客官可以移步到【验证向】关于@PostConstruct注解修饰的定时器的执行次数问题)
新建如下测试文件
Student.java
package com.aqin.custom.factoryMethod;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/** * @Description* @Authoraqin1012 AQin. * @Date2022/8/30 1:14 PM * @Version1.0 */
@Component
public class Student {public Student() {System.out.println("Student()~~~");
}private String name;
private Integer age;
public String getName() {return name;
}public void setName(String name) {this.name = name;
}public Integer getAge() {return age;
}public void setAge(Integer age) {this.age = age;
}@PostConstruct
public void init() {System.out.println("@PostConstruct -> init()");
}@PreDestroy
public void destroy() {System.out.println("@PreDestroy -> destroy()");
}}
配置文件、xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.aqin"></context:component-scan></beans>
注意⚠️
在此测试中,记得添加Student类上的@Component以及配置文件中的<context:component-scan base-package="com.aqin"></context:component-scan>,否则会报如下图的异常
执行入口
package com.aqin;
import com.aqin.custom.factoryMethod.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/** * @authoraqin1012 AQin. * @date2022/4/24 5:44 PM * @Version1.0 */
public class AqinApplication {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student.getName());
}}
执行结果
第一次执行结果:
看到输出,那么问题来了——为什么只有@PostConstruct修饰的方法被执行了,@PreDestroy修饰的呢?
这里需要显式调用下
context.close();
再次执行,
搞定🎉
最后:关于注解转换的问题
感兴趣的同学可以注意下,上面在处理被@PostConstruct和@PreDestroy注解修饰的代码中并没有出现@PostConstruct和@PreDestroy,出现的是InitAnnotationType和DestroyAnnotationType,那么@PostConstruct和@PreDestroy是在哪里被转换为InitAnnotationType和DestroyAnnotationType的?
嘿嘿(。・ω・。)ノ来一起瞅瞅~
在CommonAnnotationBeanPostProcessor的构造函数中可以看到
没错,就是在这里转换掉的(´▽`)