Spring DI(依赖注入源码分析)
程序员文章站
2022-06-17 09:43:53
...
依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
一、时序图
依赖注入时序图,描述了依赖注入过程。
二、依赖注入过程
spring依赖注入发生在getBean()方法,spring获取到Bean的定义后,并未实例化,先缓存Bean的定义,需要使用时,在进行实例化。这样能够解决依赖注入时,循环依赖问题。
Bean依赖注入入口AbstractApplicationContext类public void refresh() throws BeansException, IllegalStateException方法,该方法继续调用了protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法。
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
进入DefaultListableBeanFactory类public void preInstantiateSingletons() throws BeansException方法
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
该方法从Bean的注册表中获取Bean定义,获取class信息,诺bean是FactoryBean,及工厂Bean,需要拼接前缀&。
进入AbstractBeanFactory类public Object getBean(String name) throws BeansException方法
getBean(beanName);
继续调用AbstractBeanFactory类方法
1、protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException方法
return doGetBean(name, null, null, false);
2、protected String transformedBeanName(String name)方法
//解析别名,及把别名解析为规范名称
final String beanName = transformedBeanName(name);
经过一系列校验及判断是单例、原型模式等后,调用创建bean方法createBean。
进入AbstractAutowireCapableBeanFactory类protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException方法
return createBean(beanName, mbd, args);
继续调用AbstractAutowireCapableBeanFactory类方法
1、protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
先重IOC容器中获取,不存在则创建
//IOC容器
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();
2、protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法
instanceWrapper = createBeanInstance(beanName, mbd, args);
3、protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)方法
//初始化bean
return instantiateBean(beanName, mbd);
进入SimpleInstantiationStrategy类public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)方法
//根据策略就行初始化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
//初始化实例包装为一个BeanWrapper
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
回到AbstractAutowireCapableBeanFactory类protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException方法
继续调用AbstractAutowireCapableBeanFactory类方法
1、protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
该方法中,如果实例化Bean需要依赖注入其他Bean,那么会先走以下逻辑,源码如下:
//获取所有的后置处理器getBeanPostProcessors()
//BeanPostProcessor就是在Bean实例创建之后,在进行populateBean赋值之后,init初始化方法之前进行一次调用,init方法之后进行一 //次调用,这样一来,整个Bean的生命周期,全部掌控在了Spring之下,包括Bean实例创建new Instance(),赋值前后populateBean(), //初始化前后init(),销毁前后destroy()。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//当实例化Bean需要依赖注入其他Bean,遍历到bp如果是AutowiredAnnotationBeanPostProcessor,进入AutowiredAnnotationBeanPostProcessor类public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)方法
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
实例化Bean需要依赖注入其他Bean时,获取到getBeanPostProcessors()进行遍历,当遍历到bp是AutowiredAnnotationBeanPostProcessor时,进入AutowiredAnnotationBeanPostProcessor类public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)方法进行相关依赖的Bean实例化。
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
进入InjectionMetadata类public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable方法
metadata.inject(bean, beanName, pvs);
进入InjectedElement类protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable方法
element.inject(target, beanName, pvs);
回到DefaultListableBeanFactory类,调用public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException方法
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
该方法中会注入相关的依赖,源码如下:
//把相关的依赖bean注入
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
继续调用DefaultListableBeanFactory类方法
1、public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException方法
进入DependencyDescriptor类public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException方法
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
然后再次回到AbstractBeanFactory类public Object getBean(String name) throws BeansException方法,该方法后的执行流程已经分析。
return beanFactory.getBean(beanName);
当相关的依赖都注入,再次回到AbstractAutowireCapableBeanFactory类protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法,继续调用protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)方法
if (pvs != null) {
//对属性进行注入,注入参数的方法(注解的Bean的依赖注入除外)
applyPropertyValues(beanName, mbd, bw, pvs);
}
回到AbstractAutowireCapableBeanFactory类protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException方法
继续调用AbstractAutowireCapableBeanFactory类方法
1、protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) 方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
方法中继续调用
//Aware实现处理,为 Bean 实例对象包装相关属性,如名称,类加载器,所属容器等信息
invokeAwareMethods(beanName, bean);
//对BeanPostProcessor后置处理器的postProcessBeforeInitialization回调方法的调用,为Bean实例初始化前做一些处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用Bean实例对象初始化的方法,这个初始化方法是在 Spring Bean定义配置文件中通过init-Method属性指定的
invokeInitMethods(beanName, wrappedBean, mbd);
//对BeanPostProcessor后置处理器的postProcessAfterInitialization回调方法的调用,为Bean实例初始化之后做一些处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
三、资料地址
git地址有详细时序图,有相应的html文件可以直接浏览
地址: https://github.com/13162576590/spring-source-study
上一篇: MongoDB安装,mongodb
下一篇: 查询数据中所有表实际记录数