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

11. Spring源码篇之实例化前的后置处理器

简介

spring在创建Bean的过程中,提供了很多个生命周期,实例化前就是比较早的一个生命周期,顾名思义就是在Bean被实例化之前的处理,这个时候还没实例化,只能拿到该Bean的Class对象,如果在这个时候直接返回一个对象,那么就不用spring给我们创建了

简单使用

实现 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation方法

@Component
public class UserBean {
	public UserBean() {
		System.out.println("实例化UserBean");
	}
}

@Component
public class BeforeInstantiation implements InstantiationAwareBeanPostProcessor {
	@Override
	public Object postProcessBeforeInstantiation(@NotNull Class<?> beanClass, String beanName) throws BeansException {
		if (beanName.equals("userBean")) {
			return "1";
		}
		return null;
	}
}

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    System.out.println(context.getBean("userBean"));
}


输出结果 1

从上面的逻辑可以看出,如果beanName是userBean,那么直接返回一个
1,这个返回值是个object,任意类型都可以,如果直接返回有结果,那么这个结果就是该bean的结果,spring不会再给我们去实例化bean

源码分析

createBean源码

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

// 如果拿到Bean直接返回,也就是不会再有后面的逻辑,后面的一些扩展点会不生效
if (bean != null) {
    return bean;
}

进入 resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // 有没有 InstantiationAwareBeanPostProcessors 后置处理器
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 如果有后置处理去执行初始化前逻辑,可能获得了一个Bean
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 如果获得了Bean,由于外面是直接返回,但是Aop逻辑应该还是要有,而aop就是通过初始化后的后置处理实现的,所以需要执行
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 遍历执行postProcessBeforeInstantiation方法,可能可以直接获得到Bean
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
            return result;
        }
    }
    return null;
}


public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
    Object result = existingBean;
    // 遍历执行初始化后的逻辑postProcessAfterInitialization
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

从上面的源码逻辑得知,每个bean都会进行实例化前的操作,通过找出所有的InstantiationAwareBeanPostProcessor执行postProcessAfterInitialization方法进行扩展。

以上就是实例化前的扩展点。


欢迎关注,学习不迷路!


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

相关文章:

  • 高美GULMAY高压发生器维修X射线源维修CF160
  • 力扣513:找树左下角的值
  • 大模型研究报告 | 2024年中国金融大模型产业发展洞察报告|附34页PDF文件下载
  • 「QT」窗口类 之 QWidget 窗口基类
  • 从0学习React(11)
  • 离线 快速搭建 docker docker-compose k8s 环境
  • ElasticSearch综合练习题,ES为8版本,使用Kibana运行语句
  • SQL Server中substring的用法
  • 在Rust编程中使用泛型
  • Mysql-CRUD(增删查改)
  • PS学习笔记——新建文档/修改文档
  • 【飞控调试】DJIF450机架+Pixhawk6c mini+v1.13.3固件+好盈Platinium 40A电调无人机调试
  • 竞赛选题 深度学习验证码识别 - 机器视觉 python opencv
  • 工厂自动化中DCS软件
  • 让你彻底学会HBase
  • 11.5MyBatis(进阶)
  • 若依前后端分离版,快速上手
  • 五、Linux目录结构
  • 大模型LLM 在线量化;GPTQ\AWQ量化
  • 记录将excel表无变形的弄进word里面来
  • 【Oracle 客户端连接数据库过程解析】
  • 云计算和跨境电商:数字化未来的基石
  • 科研小白成长记37——换档
  • 使用Pandas进行时间重采样,充分挖掘数据价值
  • 详细步骤记录:持续集成Jenkins自动化部署一个Maven项目
  • gittee启动器