SpringBoot启动流程分析知识点--DI

SpringBoot启动流程分析知识点–DI

一、概述

源码基于SpringBoot 2.7.xx版本

官网:SpringBoot–DI

前置知识点–SpringBoot扩展点–BeanPostProcessor

1.1 简介

依赖注入(Dependency injection,简称DI),SpringBoot的依赖注入是通过BeanPostProcessor来完成的,不了解BeanPostProcessor的请先查看前置知识点。

1.2 常用BeanPostProcessor及其支持注入的注解

  • CommonAnnotationBeanPostProcessor
    • @Resource
    • @WebServiceRef
    • @EJB
  • AutowiredAnnotationBeanPostProcessor
    • @Autowired
    • @Value
    • @Inject

二、详解

2.1 CommonAnnotationBeanPostProcessor

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
   
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
   
        InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
        try {
   
            // 进行属性注入
            metadata.inject(bean, beanName, pvs);
        } catch (Throwable ex) {
   
            throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
        }
        return pvs;
    }
}

CommonAnnotationBeanPostProcessor 依赖注入和AutowiredAnnotationBeanPostProcessor类似,不同之处在于
AutowiredAnnotationBeanPostProcessor 重写了inject()方法

2.1.1 inject 执行注入

public class InjectionMetadata {
   
    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   
        Collection<InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
   
            for (InjectedElement element : elementsToIterate) {
   
                element.inject(target, beanName, pvs);
            }
        }
    }

    protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
            throws Throwable {
   
        // 字段注入
        if (this.isField) {
   
            Field field = (Field) this.member;
            ReflectionUtils.makeAccessible(field);
            field.set(target, getResourceToInject(target, requestingBeanName));
        } else {
   
            if (checkPropertySkipping(pvs)) {
   
                return;
            }
            try {
   
                // 方法注入
                Method method = (Method) this.member;
                ReflectionUtils.makeAccessible(method);
                method.invoke(target, getResourceToInject(target, requestingBeanName));
            } catch (InvocationTargetException ex) {
   
                throw ex.getTargetException();
            }
        }
    }
}

2.1.2 getResourceToInject

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
   
    private class ResourceElement extends LookupElement {
   

        @Override
        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
   
            return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
                    getResource(this, requestingBeanName));
        }
    }

    protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {
   
        // ……
        return autowireResource(this.resourceFactory, element, requestingBeanName);
    }

    protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {
   

        Object resource;
        Set<String> autowiredBeanNames;
        String name = element.name;

        if (factory instanceof AutowireCapableBeanFactory) {
   
            AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
            DependencyDescriptor descriptor = element.getDependencyDescriptor();
            // 如果factory不包含name,则进行依赖查找,找到当前字段/方法所匹配的Bean对象
            if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
   
                autowiredBeanNames = new LinkedHashSet<>();
                // 该查找方法和AutowiredAnnotationBeanPostProcessor中查找方法是同一个方法,详情请看2.2章节
                resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
                if (resource == null) {
   
                    throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
                }
            } else {
   
                // 根据name查找
                resource = beanFactory.resolveBeanByName(name, descriptor);
                autowiredBeanNames = Collections.singleton(name);
            }
        } else {
   
            resource = factory.getBean(name, element.lookupType);
            autowiredBeanNames = Collections.singleton(name);
        }

        if (factory instanceof ConfigurableBeanFactory) {
   
            ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
            for (String autowiredBeanName : autowiredBeanNames) {
   
                if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
   
                    beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
                }
            }
        }

        return resource;
    }
}

2.2 AutowiredAnnotationBeanPostProcessor

public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered
  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanderboy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值