• 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    输出结果 1

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

    源码分析

    createBean源码

    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    
    // 如果拿到Bean直接返回,也就是不会再有后面的逻辑,后面的一些扩展点会不生效
    if (bean != null) {
        return bean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    进入 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;
    }
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

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

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


    欢迎关注,学习不迷路!

  • 相关阅读:
    .NET下数据库的负载均衡(有趣实验)
    【CC3200AI 实验教程 1】疯壳·AI语音人脸识别(会议记录仪/人脸打卡机)-开发环境搭建
    秩零化度定理(Rank-Nullity Theorem)
    DataFrame和list之间相互转换:df.values.tolist()和pd.DataFrame()
    微软10月补丁 | 修复103个漏洞,包括2个零日漏洞,13个严重漏洞
    django创建应用程序后在项目中注册
    【校招VIP】前端链表算法之快慢指针题型
    探索数字孪生的潜力:五个最有前景的行业
    Double 4 VR智能互动系统在法律法庭上的模拟演练教学
    同为科技(TOWE)主副控智能自动断电桌面PDU插排
  • 原文地址:https://blog.csdn.net/weixin_44412085/article/details/134490113