[Java SE]JDK版本特性解读:@PostStruct[JDK1.6-JDK1.8]
1 @PostStruct
1.1 概述
定义及用途
@PostConstruct(javax.annotation.PostConstruct)注解好多人以为是Spring提供的。而实际上是Java自身的注解。
Java中该注解的说明:
@PostConstruct,该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。
PostConstruct在构造函数之后执行,init()方法之前执行。
通常地,在Spring框架中也会使用到
@PostConstruct注解。那么,整个Bean初始化的执行顺序为:
- step1 Constructor(构造方法)
- step2 @Autowired(依赖注入)
- step3 @PostConstruct(注释的方法)
应用场景
- 场景1:在静态方法中调用spring
依赖注入的Bean中的方法。
package com.example.studySpringBoot.util;
import com.example.studySpringBoot.service.MyMethorClassService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MyUtils {
private static MyUtils staticInstance = new MyUtils();
@Autowired
private MyMethorClassService myService;
@PostConstruct
public void init(){
staticInstance.myService = myService;
}
public static Integer invokeBean(){
return staticInstance.myService.add(10,20);
}
}
源码
package javax.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface PostConstruct {
}
使用示例

1.2 发展历程:[JDK 1.6-1.8]
1.2.1 始于JDK1.6 Annotations
Common Annotations 原本是
Java EE 5.0(JSR 244)规范的一部分,现在SUN把它的一部分放到了Java SE 6.0中。随着Annotation元数据功能加入到Java SE 5.0里面,很多Java 技术都会用Annotation部分代替XML文件来配置运行参数。以下列举Common Annotations 1.0里面的几个Annotations:
@Generated:用于标注生成的源代码
@Resource: 用于标注所依赖的资源,容器据此注入外部资源依赖,有基于字段的注入和基于setter方法的注入两种方式 。
@Resources:同时标注多个外部依赖,容器会把所有这些外部依赖注入
@PostConstruct:标注当容器注入所有依赖之后运行的方法,用来进行依赖注入后的初始化工作,只有一个方法可以标注为PostConstruct 。
@PreDestroy:当对象实例将要被从容器当中删掉之前,要执行的回调方法要标注为PreDestroy 作者:苦逼码农xisdn https://www.bilibili.com/read/cv7666575 出处:bilibili
1.2.2 弃于JDK1.9,止于JDK1.11
JDK 在
Java 9中已被弃用,而在Java 11中已被删除解决方法:主动引入第三方JAR包
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
1.3 原理分析
JDK提供的@PostConstruct注解,Spring是如何实现的呢?
需要先学习下BeanPostProcessor这个接口:
import org.springframework.beans.factory.config;
import ...
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
*
* 任何Bean实例化,并且Bean已经populated(填充属性) 就会回调这个方法
*
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
*
* 任何Bean实例化,并且Bean已经populated(填充属性) 就会回调这个方法
*
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
那Spring初始化是那里回调这些方法呢?
AbstractApplicationContext.finishBeanFactoryInitialization(...);
beanFactory.preInstantiateSingletons();
DefaultListableBeanFactory.getBean(beanName);
AbstractBeanFactory.doGetBean();
AbstractAutowireCapableBeanFactory.createBean(....)
populateBean(beanName, mbd, instanceWrapper);
initializeBean(...)
//调用BeanPostProcessor.postProcessBeforeInitialization()方法
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用BeanPostProcessor.postProcessBeforeInitialization()方法
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
BeanPostProcessor有个实现类CommonAnnotationBeanPostProcessor,就是专门处理@PostConstruct、@PreDestroy注解。
CommonAnnotationBeanPostProcessor的父类InitDestroyAnnotationBeanPostProcessor()
InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization()
InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata()
// 组装生命周期元数据
InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata()
// 查找@PostConstruct注释的方法
InitDestroyAnnotationBeanPostProcessor.initAnnotationType
// 查找@PreDestroy注释方法
InitDestroyAnnotationBeanPostProcessor.destroyAnnotationType
// 反射调用
metadata.invokeInitMethods(bean, beanName);
X 参考文献
- Java程序员必备基础:JDK 5-15都有哪些经典新特性 - bilibili
- jdk6新特性 - 码农家园
- JDK新特性(JDK6) [转载] - 蜂巢驻点
- 无法在Java 11中使用@PostConstruct和@PostDestroy - CSDN 【推荐】
- Spring PostConstruct and PreDestroy Annotations - baeldung 【推荐】
[Java SE]JDK版本特性解读:@PostStruct[JDK1.6-JDK1.8]的更多相关文章
- Java SE 8 新增特性
Java SE 8 新增特性 作者:Grey 原文地址: Java SE 8 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- Java SE 9 新增特性
Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- Java SE 11 新增特性
Java SE 11 新增特性 作者:Grey 原文地址:Java SE 11 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 13 新增特性
Java SE 13 新增特性 作者:Grey 原文地址:Java SE 13 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 14 新增特性
Java SE 14 新增特性 作者:Grey 原文地址:Java SE 14 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 15 新增特性
Java SE 15 新增特性 作者:Grey 原文地址:Java SE 15 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 16 新增特性
Java SE 16 新增特性 作者:Grey 原文地址:Java SE 16 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 17 新增特性
Java SE 17 新增特性 作者:Grey 原文地址:Java SE 17 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 18 新增特性
Java SE 18 新增特性 作者:Grey 原文地址:Java SE 18 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 19 新增特性
Java SE 19 新增特性 作者:Grey 原文地址: 博客园:Java SE 19 新增特性 CSDN:Java SE 19 新增特性 源码 源仓库: Github:java_new_featu ...
随机推荐
- JAVA基础Day3-用户交互Scanner/顺序结构/选择结构/循环结构
一.用户交互Scanner JAVA提供了一个工具类,可以用来获取用户的输入. java.util.Scanner是Java5的新特征,可以通过Scanner类来获取用户的输入. 基本语法: Scan ...
- windows系统下查找开放端口的监听程序
C:\Program Files (x86)\Nmap>nmap 127.0.0.1Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-15 1 ...
- day28_常用模块——hashlib,logging模块
hashlib(摘要算法) Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度 ...
- 洛谷 P2105 K皇后 题解
START: 2021-08-06 16:34:44 题目链接: https://www.luogu.com.cn/problem/P2105 题目详情: 小 Z 最近捡到了一个棋盘,他想在棋盘上摆放 ...
- 5vue 样式绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- pg_dump导出表时正则匹配多个表,pg_dump导出表
报错信息:pg_dump: 错误: 没有找到符合的表 报错语句:C:\Users\Admin>pg_dump -h172.16.3.159 -p5432 -dchisapp -nmchs -Um ...
- Android 自定义View (二)
一.前言 上节 通过一个简单的旋转环对自定义view作了一个基本的认识,本文将大致讲解下实现的思路以及对该view的一些可能的改进. 二.思路 主要通过重写 view 中的 onDraw() 方法,利 ...
- MySQL使用bin-log将数据恢复到某个时间点
binlog的三种模式 statement:记录每一条修改数据的sql row:保存哪条记录被修改 mixed:兼顾前两者的优点. # 查看binlog有没有开启 SHOW VARIABLES LIK ...
- 静态类型和动态类型VS强类型和弱类型
强类型语言和静态类型语言有什么区别? 静态类型的语言具有类型系统,该类型系统在实现时由实现(编译器或解释器)检查.类型检查拒绝某些程序,并且通过检查的程序通常带有一些保证.例如,编译器保证不对浮点数使 ...
- 表单笔记-Antd(Form)
antd表单使用笔记 import React, { useState, useEffect, useRef } from "react"; import { Form, Inpu ...