@Autowired依赖注入源码分析

本文详细探讨了Spring框架中@Autowired依赖注入的源码实现,从入口Refresh()开始,逐步解析预解析过程,包括findAutowiringMetadata、buildAutowiringMetadata和InjectionMetadata的构建。接着介绍了注入过程,如populateBean、postProcessProperties和inject方法,特别是属性自动注入AutowiredFieldElement.inject()和根据类型注入的策略determineAutowireCandidate。文章还涵盖了@Primary和@Priority注解的用法及其在依赖注入中的作用。
摘要由CSDN通过智能技术生成

  1. 什么是依赖注入?
  2. 依赖注入用到了哪些技术?
  3. 依赖注入的时机?
  4. @Autowired原理?类型注入说明?
  5. 属性注入与依赖注入的区别
  6. @Autowired、@Value、@Resource 三者区别
  7. 根据名称注入与根据类型注入区别
  8. @Primary注解用法,作用
  9. @Priority注解用法,作用

入口Refresh()

依赖注入发生在Spring 容器的初始化过程中,先与解析再执行依赖注入

//注册AutoWriedAnnotaionBeanPostProcessor
registerBeanPostProcessors(beanFactory);

//初始化Bean
finishBeanFactoryInitialization(beanFactory);

//进入getBean()->doGetBean()->createBean()->doCreateBean()
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
   

   /*省略代码*/

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
   
        if (!mbd.postProcessed
            
            	//预解析
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
   
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
   
        if (logger.isTraceEnabled()) {
   
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
   
        //依赖注入
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
	/*省略代码*/
}

预解析过程

预解析过程就是获取此Bean中的所有属性和方法,然后遍历判断是否有@Autowired、@Value、@Resource注解,最后生成InjectionMetadata类存储在缓存之中

1.通过class获取Bean中的所有字段和方法
2.遍历,执行回调函数findAutowiredAnnotation
3.判断是否有@Autowired注解和@Value注解,如果有进行存储List
4.最有根据class和List生产的InjectionMetadata


1.注册AutoWriedAnnotationBeanPostProcessor

2.Bean工厂通过getSingleton(beanName)判断Bean是否存在,存在则返回

3.实例化Bean,得到Bean的包装类  CglibSubclassingInstantiationStrategy  动态代理实例化包装类

4.实现注入元素的预解析:applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);


findAutowiringMetadata(beanName, beanType, null)

获取InjectionMetadata类,此类中存储了当前Bean以及该Bean依赖的Bean(list)

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
   
    // Fall back to class name as cache key, for backwards compatibility with custom callers.
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // Quick check on the concurrent map first, with minimal locking.
    InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
   
        synchronized (this.injectionMetadataCache) {
   
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
   
                if (metadata != null) {
   
                    metadata.clear(pvs);
                }
                //如果缓存中没有则执行进行构建(遍历)
                metadata = buildAutowiringMetadata(clazz);
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}

buildAutowiringMetadata()

获取该Bean的所有属性和方法判断是否有注解

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
   
    	//存储该Bean的依赖的List
		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
   
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
			//Fileds
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
   
				AnnotationAttributes ann = findAutowiredAnnotation(field);
				if (ann != null) {
   
					if (Modifier.isStatic(field.getModifiers())) {
   
						if (logger.isInfoEnabled()) {
   
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
			//method
			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
   
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
   
					return;
				}
				AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值