Spring @Autowired 注解原理

Spring @Autowired 注解原理

1.@Autowired 使用

@ComponentScan("org.example.bean")
public class AnnoContextDemo {

    @Autowired
    private User user;


    public static void main(String[] args) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnoContextDemo.class);

        User user1 = context.getBean(AnnoContextDemo.class).user;

        System.out.println("user1 = " + user1);
    }


}

被扫描的组件配置类

@Configuration
public class BeanConfig {

    @Bean
    public User user(){
        return new User(21,"张三");
    }

}

输出结果

user1 = User{age=21, name='张三'}

2.依赖自动注入原理

定位@Autowired所在包 org.springframework.beans.factory.annotation.Autowired

找到同包下 AutowiredAnnotationBeanPostProcessor

Spring @Autowired 注解原理_第1张图片

AutowiredAnnotationBeanPostProcessor 的类继承图如下

Spring @Autowired 注解原理_第2张图片

AutowiredAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor与

MergedBeanDefinitionPostProcessor两个BeanPostProcessor后置处理器接口

  1. MergedBeanDefinitionPostProcessor 此接口主要有两个方法 抽象方法 postProcessMergedBeanDefinition 默认方法 resetBeanDefinition

  2. InstantiationAwareBeanPostProcessor 此接口 抽象方法 postProcessBeforeInstantiation ,postProcessAfterInstantiation ,默认方法 postProcessProperties ,默认过时方法 postProcessPropertyValues

想搞清楚@Autowried注入原理,先得知道这些接口对应方法执行的先后顺序 跟踪ApplicationContext.refresh方法,调用链路如下

ApplicationContext.refresh() -> AbstractApplicationContext.finishBeanFactoryInitialization() -> ConfigurableListableBeanFactory.preInstantiateSingletons() - > AbstractBeanFactory.getBean() -> AbstractBeanFactory.doGetBean() -> AbstractBeanFactory.getSingleton() -> AbstractBeanFactory.createBean()

实例化前

-> resolveBeforeInstantiation() 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()前置方法 如果返回不为null,将执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()后置方法。

创建bean实例阶段

-> doCreateBean() -> createBeanInstance 反射创建bean实例

-> applyMergedBeanDefinitionPostProcessors() 执行 MergedBeanDefinitionPostProcessor.MergedBeanDefinitionPostProcessor方法 合并bean定义信息

属性注入阶段

-> populateBean() -> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 后置处理方法 -> 执行InstantiationAwareBeanPostProcessor.postProcessProperties -> InstantiationAwareBeanPostProcessor.postProcessPropertyValues -> applyPropertyValues 执行属性注入

初始化阶段

-> initializeBean() -> BeanPostProcessor.postProcessBeforeInitialization() 执行前置方法 -> invokeInitMethods() 反射调用初始化方法 -> BeanPostProcessor.postProcessAfterInitialization 执行后置方法

收尾注册bean

->registerDisposableBeanIfNecessary() 注册bean

通过上面追踪refresh()方法我们可知,spring容器将先调用 AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition方法,然后执行 postProcessProperties 方法

3. postProcessMergedBeanDefinition 查找需要自动注入的字段或方法

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

进入findAutowiringMetadata方法

	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);
					}
					//查找类的字段,方法,是否有需要自动注入对象的元素,封装InjectionMetadata
					metadata = buildAutowiringMetadata(clazz);
					//放入缓存中,供后面调用取出
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

进入 buildAutowiringMetadata 方法

private InjectionMetadata buildAutowiringMetadata(Class clazz) {
		//判断当前类是否有使用autowiredAnnotationTypes容器中的注解
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
			return InjectionMetadata.EMPTY;
		}

		List elements = new ArrayList<>();
		Class targetClass = clazz;

		do {
			final List currElements = new ArrayList<>();
			//反射遍历类中所有字段
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				//字段上是否有标注自动装配相关的注解
				MergedAnnotation 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);
					//封装InjectionMetadata
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
			
			//反射遍历类中所有方法
			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
					//方法上是否有标注自动装配相关的注解
				MergedAnnotation ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static methods: " + method);
						}
						return;
					}
					if (method.getParameterCount() == 0) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation should only be used on methods with parameters: " +
									method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					//封装InjectionMetadata
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			});

			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return InjectionMetadata.forElements(elements, clazz);
	}

this.autowiredAnnotationTypes 为set集合,容器内为需要自动注入的注解类

private final Set> autowiredAnnotationTypes = new LinkedHashSet<>(4);
	public AutowiredAnnotationBeanPostProcessor() {
	## 1.@Autowired
		this.autowiredAnnotationTypes.add(Autowired.class);
  ## 2.@Value
		this.autowiredAnnotationTypes.add(Value.class);
		try {
 ## [email protected]  JSR-330规范中定义的一个注解
			this.autowiredAnnotationTypes.add((Class)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

4.postProcessProperties 需要自动注入的元素从容器中获取bean后注入

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		//首先从缓存中取出需要自动注入的元素(包括字段,方法)
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			//进行注入
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

进入 metadata.inject() 方法

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection checkedElements = this.checkedElements;
		Collection elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			//遍历需要注入的元素
			for (InjectedElement element : elementsToIterate) {
				//不同类型调用各自inject方法
				element.inject(target, beanName, pvs);
			}
		}
	}

字段处理逻辑

通过 resolveFieldValue 方法,找到需要依赖的bean(单个或集合),通过 Filed.set方法注入

		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				try {
					value = resolvedCachedArgument(beanName, this.cachedFieldValue);
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Unexpected removal of target bean for cached argument -> re-resolve
					value = resolveFieldValue(field, bean, beanName);
				}
			}
			else {
			//查找依赖的bean
				value = resolveFieldValue(field, bean, beanName);
			}
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				//反射设置值
				field.set(bean, value);
			}
		}

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class type = descriptor.getDependencyType();
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}
		
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			//字段非集合类型时bean时查找方法
			Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				Map.Entry entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

findAutowireCandidates() 会调用 BeanFactoryUtils.beanNamesForTypeIncludingAncestors

底层通过类似双亲委派模型,找出所有的bean

	public static String[] beanNamesForTypeIncludingAncestors(
			ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) {

		Assert.notNull(lbf, "ListableBeanFactory must not be null");
		String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
		if (lbf instanceof HierarchicalBeanFactory) {
			HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
			if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
				String[] parentResult = beanNamesForTypeIncludingAncestors(
						(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
				result = mergeNamesWithParent(result, parentResult, hbf);
			}
		}
		return result;
	}

你可能感兴趣的:(spring,java,后端)