当前位置: 首页 > article >正文

SpringBoot日常:Spring之@PostConstruct解析

简介

spring的Bean在创建的时候会进行初始化,而初始化过程会解析出@PostConstruct注解的方法,并反射调用该方法。
@PostConstruct 的使用和特点

  • 只有一个非静态方法能使用此注解;
  • 被注解的方法不得有任何参数;
  • 被注解的方法返回值必须为void;
  • 被注解的方法不得抛出已检查异常;
  • 被注解的方法只会被执行一次;

源码分析

在Bean创建完成后,进行初始化的过程中,主要包含了初始化的前置、后置处理,以及初始化方法的调用。@PostConstruct注解将在applyBeanPostProcessorsBeforeInitialization这个前置处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	//遍历了在spring启动过程中被注册的BeanPostProcessor接口,
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		//调用其前置方法。
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

@PostConstruct注解是会被一个专门的BeanPostProcessor接口的具体实现类来处理的InitDestroyAnnotationBeanPostProcessor

//org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	// 元数据解析  注解的初始化方法也会在这里被找到
	LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
	try {
		// 触发初始化方法
		metadata.invokeInitMethods(bean, beanName);
	}
	catch (InvocationTargetException ex) {
		throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
	}
	return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
	Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
	Collection<LifecycleElement> initMethodsToIterate =
			(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
	if (!initMethodsToIterate.isEmpty()) {
		for (LifecycleElement element : initMethodsToIterate) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
			}
			//  调用
			element.invoke(target);
		}
	}
}

注意:在CommonAnnotationBeanPostProcessor这个后置处理器的构造方法中,@PostConstruct注解被设置为了initAnnotationType的值

//org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

public CommonAnnotationBeanPostProcessor() {
	setOrder(Ordered.LOWEST_PRECEDENCE - 3);
	setInitAnnotationType(PostConstruct.class);
	setDestroyAnnotationType(PreDestroy.class);
	ignoreResourceType("javax.xml.ws.WebServiceContext");

	// java.naming module present on JDK 9+?
	if (jndiPresent) {
		this.jndiFactory = new SimpleJndiBeanFactory();
	}
}

应用场景

@PostConstruct不算一个扩展点,但是也有比较实用的应用场景,主要在Servlet初始化之前加载一些缓存数据,比如

  • 数据字典,
  • 读取properties配置文件

代码示例

@Component
@Slf4j
public class TagPostConstruct {

    @Autowired
    private TestAutowired testAutowired;

    public TagPostConstruct(){
        log.info("TagPostConstruct构造方法------run");
    }

    @PostConstruct
    public void myPostConstruct() {
        log.info("PostConstruct------run");
    }
}

@Slf4j
@Component
public class TestAutowired {

    public TestAutowired(){
        log.info("TestAutowired构造方法------run");
    }
}

运行示例

可以看出@PostConstruct注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)-> @Autowired(依赖注入)-> @PostConstruct(注解的方法);
在这里插入图片描述


http://www.kler.cn/a/281716.html

相关文章:

  • vue3项目执行npm install下载依赖报错问题排查方法
  • Linux进阶:软件安装、网络操作、端口、进程等
  • C#获取视频第一帧_腾讯云媒体处理获取视频第一帧
  • 生成式语言模型 三范式 预训练、微调、强化反馈学习
  • 5G与4G互通的桥梁:N26接口
  • Altenergy电力系统 status_zigbee SQL注入漏洞复现(CVE-2024-11305)
  • Windows中Jupyter notebook设置默认目录
  • 全志/RK安卓屏一体机:医疗手推车解决方案,支持鸿蒙国产化
  • 中间件实时监控,运维难题一站解决
  • 【LeetCode】搜索旋转排序数组[python]
  • 【Linux】如何用一条命令终止某个后台进程?
  • AI学习记录 - 模型训练中怎么反向传播以及学习率的影响
  • CSS 的font-synthesis属性与中文体验增强
  • 手机号码归属地查询如何用PHP进行调用
  • zoom 会议 javascript 转录例子
  • 第四十篇-TeslaP40+Ollama+Ollama-WebUI(自编译)
  • Python-MNE-源定位和逆问题01:源估计(SourceEstimate)数据结构
  • Nginx 部署前端 Vue 项目全攻略
  • Spring WebFlux – CVE-2023-34034 – 撰写和概念验证
  • Jmeter下载、配置环境变量
  • 【vue3】wangEditor 5在vue3中的使用
  • 【KDD2024】大数据基础工程技术集群异常检测论文入选
  • 【netty系列-08】深入Netty组件底层原理和基本实现
  • stable-diffusion-webui 部署 ,启用 api 服务
  • TPM管理培训究竟需要多少天?完整攻略在此
  • 光伏设计中组串逆变和微型逆变是什么意思?有什么区别?