1. 用法
可以用@Autowired作用于字段或者方法上,下面代码演示注解作用于字段上:
// 被注入的bean@Servicepublic class AService {public void run(){ System.out.println("success autowire !"); } }复制代码
@RestControllerpublic class HelloController { @Autowired private AService aService; }复制代码
2. 原理
首先看Autowired源码
/* * @author Juergen Hoeller * @author Mark Fisher * @author Sam Brannen * @since 2.5 * @see AutowiredAnnotationBeanPostProcessor * @see Qualifier * @see Value */ @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }复制代码
从注释中可以看出,实现类是在AutowiredAnnotationBeanPostProcessor中实现的。并且required属性默认为true,说明运行的时候,被@Autowired注解标记的bean必须存在,否则会报错。大家可以试试将上面示例代码中的类AService去掉@Service注解,在启动准会报错,原因见后面源码分析。
AutowiredAnnotationBeanPostProcessor
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { ··· }复制代码
因为之前我debug过Spring中bean的初始化流程,先贴出总结,以后有时间单独再写一篇。 bean初始化执行顺序:
- Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)------InstantiationAwareBeanPostProcessor
- Object postProcessAfterInitialization(Object bean, String beanName) ------BeanPostProcessor
- void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)------MergedBeanDefinitionPostProcessor
- boolean postProcessAfterInstantiation(Object bean, String beanName)------InstantiationAwareBeanPostProcessor
- PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)------InstantiationAwareBeanPostProcessor
- void invokeAwareMethods(String beanName, Object bean)
- Object postProcessBeforeInitialization(Object bean, String beanName) ------BeanPostProcessor
- invokeInitMethods
- 先调用实现了InitializingBean接口的afterPropertiesSet()方法
- 调用initMethod()方法
- postProcessAfterInitialization ------BeanPostProcessor
所以,这里的AutowiredAnnotationBeanPostProcessor中方法执行前后顺序是
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
1. 执行 postProcessMergedBeanDefinition方法
将标注@Autowired注解的字段或者方法存入InjectionMetadata对象中
@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } 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); // 将构造好的InjectionMetadata对象放入injectionMetadataCache缓存中 this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; } private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { // 判断该类是否携带@Autowired或者@Value(在类型,方法或字段上) if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); // 遍历该类所有字段是否带有@Autowired或者@Value ReflectionUtils.doWithLocalFields(targetClass, field -> { MergedAnnotation<?> ann = findAutowiredAnnotation(field); if (ann != null) { // 字段不能用static修饰,否则注入不了 if (Modifier.isStatic(field.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static fields: " + field); } return; } // 获取@Autowired中的属性required,默认为true boolean required = determineRequiredStatus(ann); // 创建一个AutowiredFieldElement封装字段信息以及required值 currElements.add(new AutowiredFieldElement(field, required)); } }); // 遍历该类所有方法是否带有@Autowired或者@Value 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); // 创建一个AutowiredMethodElement封装字段信息以及required值 currElements.add(new AutowiredMethodElement(method, required, pd)); } }); elements.addAll(0, currElements); //迭代,继续遍历父类 targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); // 封装成InjectionMetadata对象 return InjectionMetadata.forElements(elements, clazz); }复制代码
2. 执行 postProcessPropertyValues 方法
@Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { //从缓存中injectionMetadataCache取出InjectionMetadata对象 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; }复制代码
然后进入到 org.springframework.beans.factory.annotation.InjectionMetadata#inject方法
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) { if (logger.isDebugEnabled()) { logger.debug("Processing injected element of bean '" + beanName + "': " + element); } // 这里因为AutowiredAnnotationBeanPostProcessor重写了InjectedElement element.inject(target, beanName, pvs); } } }复制代码
在AutowiredAnnotationBeanPostProcessor中重写了InjectedElement,分别有AutowiredMethodElement与AutowiredFieldElement。 因为我们例子中是在字段上标注的注解,所以我们这里以AutowiredFieldElement举例:
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {@Overrideprotected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try {// 获取被@Autowired标注的bean ‘Aservice’ value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } // 反射给属性赋值if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } }复制代码
一路追踪.DefaultListableBeanFactory#resolveDependency代码 DefaultListableBeanFactory#doResolveDependency
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { ··· Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); // 如果matchingBeans找不到对应的bean则返回null if (matchingBeans.isEmpty()) { // required默认为true,那么这里会抛出NoSuchBeanDefinitionException异常 if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } ···下面实例化bean代码省略 // 不为null就根据matchingBeans获取对应的bean实例 } private void raiseNoMatchingBeanFound( Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException { checkBeanNotOfRequiredType(type, descriptor); throw new NoSuchBeanDefinitionException(resolvableType, "expected at least 1 bean which qualifies as autowire candidate. " + "Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations())); }复制代码
DefaultListableBeanFactory#findAutowireCandidates 终于发现了关键代码
protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); ...复制代码
如果默认的@Autowired,里面required为true,那么这里如果将类'Aservice'上的注解@Service去掉,那么在上面这行代码中找不到对应的beanName,就会返回null。 找到的话,就正常获取bean实例返回,最后通过反射赋值。
3. 总结
其实@Resource注解源码跟@Autowired实现类似,实现类是在CommonAnnotationBeanPostProcessor中,大家可以尝试自己看一下。 还有这篇文章中,AutowiredAnnotationBeanPostProcessor该类不仅仅处理了@Autowired注解,其实还有个@Value注解,这里我没写,下次有时间在分析。
最后,@Autowired注解作用在字段上,其实就是通过AutowiredFiledElement中的field.set(bean, valu)注入,作用在方法上,就是通过AutowiredMethodElement中的method.invoke(bean, arguments)。