Spring 依赖注入原理

Spring 面试 About 9,307 words

版本

spring-context 5.2.6.RELEASE

依赖注入

AutowiredAnnotationBeanPostProcessor处理@Autowired@Value注解。

CommonAnnotationBeanPostProcessor处理@Resource

案例

@Service
public class TestService {

    @Autowired
    private TestDao testDao;

    @Value("TestValue")
    private String testValue;

    @Resource
    private ResourceBean resourceBean;

    public TestService() {
        System.out.println("TestService construct");
    }
}

@Repository
public class TestDao {

    public TestDao() {
        System.out.println("TestDao construct");
    }
}

@Component
public class ResourceBean {

    public ResourceBean() {
        System.out.println("ResourceBean construct");
    }
}

原理

实例化单例bean

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
        }
    }

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }
}

doCreateBean方法中进行createBeanInstance实例化,和populateBean中给成员变量赋值。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;

        if (instanceWrapper == null) {
            // 使用反射创建实例
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();

        // Initialize the bean instance.
        Object exposedObject = bean;

        // 填充实例中的属性
        populateBean(beanName, mbd, instanceWrapper);

        exposedObject = initializeBean(beanName, exposedObject, mbd);

        return exposedObject;
    }
}

populateBean方法中对BeanPostProcessor所有后置处理器进行遍历,postProcessProperties处理成员变量的赋值。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 对实现了 InstantiationAwareBeanPostProcessor 接口的后置处理器进行成员变量处理
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                pvs = pvsToUse;
            }
        }
    }
}

AutowiredAnnotationBeanPostProcessor处理@Autowired@Value注解。

抽象类InstantiationAwareBeanPostProcessorAdapter实现了SmartInstantiationAwareBeanPostProcessor接口,而接口SmartInstantiationAwareBeanPostProcessor继承自InstantiationAwareBeanPostProcessor

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        // 注入成员变量属性
        metadata.inject(bean, beanName, pvs);
        return pvs;
    }
}

CommonAnnotationBeanPostProcessor处理@Resource

// org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties
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);
        // 注入成员变量属性
        metadata.inject(bean, beanName, pvs);
        return pvs;
    }
}

InjectedElementinject注入

// org.springframework.beans.factory.annotation.InjectionMetadata#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);
            }
        }
    }
}

@Autowired@Value注入流程走AutowiredFieldElement复写的inject方法。

field.set(bean, value);就是对成员变量赋值

// org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
    @Override
    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Field field = (Field) this.member;
        Object value;

        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
        TypeConverter typeConverter = beanFactory.getTypeConverter();
        try {
            // 解析注入的 @Autowired 依赖,如果没有实例化和填充属性,则先进行依赖的实例化和填充属性
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
        }
        if (value != null) {
            // 将 private 的属性设置为可以被反射访问
            ReflectionUtils.makeAccessible(field);
            // 对字段赋值
            field.set(bean, value);
        }
    }
}

@Resource注入流程走InjectionMetadata中抽象类InjectedElementinject方法。

field.set(target, getResourceToInject(target, requestingBeanName));:对成员变量赋值

// org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject
public class InjectionMetadata {
    // @Resource 走的此处的 inject
    public abstract static class InjectedElement {
        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();
                }
            }
        }
    }
}

完整调用栈

inject:670, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation)
inject:130, InjectionMetadata (org.springframework.beans.factory.annotation)
postProcessProperties:399, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
populateBean:1422, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1268650975 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$32)
getSingleton:226, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:895, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:878, AbstractApplicationContext (org.springframework.context.support)
refresh:550, AbstractApplicationContext (org.springframework.context.support)
<init>:89, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:13, Test6 (com.example.learn)
Views: 2,040 · Posted: 2021-12-17

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh