目录
AutowiredAnnotationBeanPostProcessor 何时被注册到 BeanFactory?
AnnotationConfigUtils#registerAnnotationConfigProcessors
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
1.postProcessMergedBeanDefinition 方法介绍
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
2.postProcessPropertyValues 方法介绍
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
代码块6:AutowiredFieldElement#inject
Spring IoC源码学习全系列
Spring IoC源码学习:ApplicationContext 刷新前的配置
Spring IoC源码学习:obtainFreshBeanFactory详解
Spring IoC源码学习:parseDefaultElement详解
Spring IoC源码学习:parseCustomElement详解
Spring IoC源码学习:context:component-scan节点详解
Spring IoC源码学习:invokeBeanFactoryPostProcessors详解
Spring IoC源码学习:registerBeanPostProcessors详解
Spring IoC源码学习:finishBeanFactoryInitialization详解
Spring IoC源码学习:createBean详解(上)
Spring IoC源码学习:createBean详解(下)
Spring IoC源码学习:finishRefresh详解
在Spring IoC:createBean详解(上)中代码块4.5 和Spring IoC:createBean详解(下)中代码块1、代码块4的 7.1.1 我们遗留了一个解析——@Autowire 注解的解析。之所以单独提出来,是因为在我现在接触的项目中,使用 @Autowire 注解的比例非常高,可以说基本用过 Spring 的同学都接触过这个注解,重要性不言而喻。因此,单独拿出来,较详细的介绍一下。
本文只会单独介绍 @Autowire 的部分内容,具体 @Autowire 注解的完整过程,需要结合Spring IoC:createBean详解(上)中代码块4.5 和Spring IoC:createBean详解(下)中代码块1、代码块4的 7.1.1 去看。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <!-- component-scan包含了annotation-config的效果 --> <context:component-scan base-package="com.joonwhee.open.demo.service"/> <context:annotation-config/> </beans>
要使用@Autowire 注解,可以通过 <context:component-scan /> 或 <context:annotation-config/> 来开启,其中前者是包含了后者的效果的,因此现在一般都使用 <context:component-scan /> 即可。
@Service public class ConstructorServiceImpl implements ConstructorService { // 1.属性注入 @Autowired private UserService userService; private final DemoService demoService; // 2.构造函数注入 @Autowired public ConstructorServiceImpl(DemoService demoService) { this.demoService = demoService; } }
该代码中使用了目前最常见的两种注入方式:1)属性注入;2)构造函数注入。
以我自己为例,我周围最常用的是:属性注入,但是 Spring 团队建议使用的方式是:构造函数注入,当你使用属性注入时,鼠标移到属性上的 @Autowire 就可以看到如下图的提示,并且可以通过快捷键将属性注入直接修改成构造函数注入。
构造函数的常见优点是:
1. 保证依赖不可变(final 关键字)
2. 保证依赖不为空(省去了检查)
3. 以完全初始化的状态返回到客户端(调用)代码
4. 避免了循环依赖
5. 提升了代码的可复用性
构造函数的常见缺点是:
1. 构造函数会有很多参数。
2. 有些类是需要默认构造函数的,一旦使用构造函数注入,就无法使用默认构造函数。
3. 这个类里面的有些方法并不需要用到这些依赖。
这些优点我看了下,个人觉得还好,只要不瞎用,其实使用属性注入并不会有什么问题。至于使用哪一种,就看个人喜好了。
@Autowire 注解的功能实现都是由 AutowiredAnnotationBeanPostProcessor 实现,AutowiredAnnotationBeanPostProcessor 的继承关系如下图:
源码解析
AutowiredAnnotationBeanPostProcessor 何时被注册到 BeanFactory?
在Spring IoC:context:component-scan节点详解中的代码块17就有AutowiredAnnotationBeanPostProcessor 被注册到 BeanFactory 的代码,如下:
AnnotationConfigUtils#registerAnnotationConfigProcessors
查看该方法的上下文,请参考:Spring IoC:context:component-scan节点详解中的代码块17。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { // 1.设置dependencyComparator属性 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { // 2.设置autowireCandidateResolver属性(设置自动注入候选对象的解析器,用于判断BeanDefinition是否为候选对象) beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); // 3.注册内部管理的用于处理@Configuration注解的后置处理器的bean if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // 3.1 registerPostProcessor: 注册BeanDefinition到注册表中 beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 4.注册内部管理的用于处理@Autowired、@Value、@Inject以及@Lookup注解的后置处理器的bean if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 5.注册内部管理的用于处理@Required注解的后置处理器的bean if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 6.注册内部管理的用于处理JSR-250注解(例如@Resource, @PostConstruct, @PreDestroy)的后置处理器的bean // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 7.注册内部管理的用于处理JPA注解的后置处理器的bean // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 8.注册内部管理的用于处理@EventListener注解的后置处理器的bean if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // 9.注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
在该代码的第4点注册了 AutowiredAnnotationBeanPostProcessor,具体看 registerAnnotationConfigProcessors方法的调用方,可以看到 AnnotationConfigBeanDefinitionParser 和 ComponentScanBeanDefinitionParser,而这两个正是<context:component-scan /> 和 <context:annotation-config/> 的 bean 定义解析器。
构造函数注入通常来说有两种:1)xml 配置注入;2)@Autowire 注解注入;本文只讨论 @Autowire 注解注入。
AutowiredAnnotationBeanPostProcessor 中重写的方法不多,直接找一下就可以找到跟构造函数相关的方法:determineCandidateConstructors,该方法被定义在 SmartInstantiationAwareBeanPostProcessor 接口中,主要作用是:确定要用于给定 bean 的候选构造函数。
在 Spring IoC 的过程中,调用的入口在Spring IoC:createBean详解(上)中的代码块4.5,下面介绍下 determineCandidateConstructors 方法。
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
查看该方法的上下文,请参考:Spring IoC:createBean详解(上)中的代码块4.5。
@Override public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException { // Let's check for lookup methods here.. // @Lookup注解检查 if (!this.lookupMethodsChecked.contains(beanName)) { try { ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Lookup lookup = method.getAnnotation(Lookup.class); if (lookup != null) { LookupOverride override = new LookupOverride(method, lookup.value()); try { RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition"); } } } }); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Lookup method resolution failed", ex); } catch (NoClassDefFoundError err) { throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() + "] for lookup method metadata: could not find class that it depends on", err); } // 已经检查过的添加到lookupMethodsChecked this.lookupMethodsChecked.add(beanName); } // Quick check on the concurrent map first, with minimal locking. // 1.构造函数解析,首先检查是否存在于缓存中 Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { // Fully synchronized resolution now... // 2.加锁进行操作 synchronized (this.candidateConstructorsCache) { // 3.再次检查缓存,双重检测 candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { // 存放原始的构造函数(候选者) Constructor<?>[] rawCandidates; try { // 4.获取beanClass声明的构造函数(如果没有声明,会返回一个默认的无参构造函数) rawCandidates = beanClass.getDeclaredConstructors(); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); } // 存放使用了@Autowire注解的构造函数 List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length); // 存放使用了@Autowire注解,并且require=true的构造函数 Constructor<?> requiredConstructor = null; // 存放默认的构造函数 Constructor<?> defaultConstructor = null; // 5.遍历原始的构造函数候选者 for (Constructor<?> candidate : rawCandidates) { // 6.获取候选者的注解属性 AnnotationAttributes ann = findAutowiredAnnotation(candidate); if (ann == null) { // 7.如果没有从候选者找到注解,则尝试解析beanClass的原始类(针对CGLIB代理) Class<?> userClass = ClassUtils.getUserClass(beanClass); if (userClass != beanClass) { try { Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes()); ann = findAutowiredAnnotation(superCtor); } catch (NoSuchMethodException ex) { // Simply proceed, no equivalent superclass constructor found... } } } // 8.如果该候选者使用了@Autowire注解 if (ann != null) { if (requiredConstructor != null) { // 8.1 之前已经存在使用@Autowired(required = true)的构造函数,则不能存在其他使用@Autowire注解的构造函数,否则抛异常 throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } // 8.2 获取注解的require属性值 boolean required = determineRequiredStatus(ann); if (required) { if (!candidates.isEmpty()) { // 8.3 如果当前候选者是@Autowired(required = true),则之前不能存在其他使用@Autowire注解的构造函数,否则抛异常 throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate); } // 8.4 如果该候选者使用的注解的required属性为true,赋值给requiredConstructor requiredConstructor = candidate; } // 8.5 将使用了@Autowire注解的候选者添加到candidates candidates.add(candidate); } else if (candidate.getParameterTypes().length == 0) { // 8.6 如果没有使用注解,并且没有参数,则为默认的构造函数 defaultConstructor = candidate; } } // 9.如果存在使用了@Autowire注解的构造函数 if (!candidates.isEmpty()) { // Add default constructor to list of optional constructors, as fallback. // 9.1 但是没有使用了@Autowire注解并且required属性为true的构造函数 if (requiredConstructor == null) { if (defaultConstructor != null) { // 9.2 如果存在默认的构造函数,则将默认的构造函数添加到candidates candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isWarnEnabled()) { logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - " + "this constructor is effectively required since there is no " + "default constructor to fall back to: " + candidates.get(0)); } } // 9.3 将所有的candidates当作候选者 candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]); } else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) { // 10.如果candidates为空 && beanClass只有一个声明的构造函数(非默认构造函数),则将该声明的构造函数作为候选者 candidateConstructors = new Constructor<?>[]{rawCandidates[0]}; } else { // 11.否则返回一个空的Constructor对象 candidateConstructors = new Constructor<?>[0]; } // 12.将beanClass的构造函数解析结果放到缓存 this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } } // 13.返回解析的构造函数 return (candidateConstructors.length > 0 ? candidateConstructors : null); }
6.获取候选者的注解属性,见代码块1详解。
关于8.1 和 8.3 的异常校验,说的简单点:在一个 bean 中,只要有构造函数使用了 “@Autowired(required = true)” 或“@Autowired”,就不允许有其他的构造函数使用 “@Autowire”;但是允许有多个构造函数同时使用“@Autowired(required = false)”。
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) { // 1.判断ao是否有被注解修饰 if (ao.getAnnotations().length > 0) { // 2.检查是否有autowiredAnnotationTypes中的注解:@Autowired、@Value(@Value无法修饰构造函数) for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) { // 3.拿到注解的合并注解属性,@Autowire在这边拿到,required=true(默认属性) AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type); if (attributes != null) { return attributes; } } } return null; }
确定了要用于给定 bean 的候选构造函数后,之后的逻辑就是执行构造函数自动注入,该逻辑在Spring IoC:createBean详解(上)中的代码块5已经介绍。
属性注入通常来说有两种:1)xml 配置注入;2)@Autowire 注解注入;本文只讨论 @Autowire 注解注入。
AutowiredAnnotationBeanPostProcessor 中跟属性注入有关的方法出口有两个:postProcessMergedBeanDefinition 和postProcessPropertyValues。
1.postProcessMergedBeanDefinition 方法介绍
postProcessMergedBeanDefinition 被定义在 MergedBeanDefinitionPostProcessor 接口中,该方法的主要作用是:对指定 bean 的给定 MergedBeanDefinition 进行后置处理。
在AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行预解析,并放到 injectionMetadataCache 缓存中,用于后续使用。
在 Spring IoC 的过程中,调用的入口在:Spring IoC:createBean详解(下)中的代码块1,下面介绍下 postProcessMergedBeanDefinition 方法。
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
查看该方法的上下文,请参考:Spring IoC:createBean详解(下)中的代码块1。
@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanType != null) { // 1.在指定Bean中查找使用@Autowire注解的元数据 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); // 2.检查元数据中的注解信息 metadata.checkConfigMembers(beanDefinition); } }
1.在指定 bean 中查找使用 @Autowire 注解的元数据,见代码块2详解。
2.检查元数据中的注解信息,见代码块4详解。
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. // 1.设置cacheKey的值(beanName 或者 className) String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. // 2.检查beanName对应的InjectionMetadata是否已经存在于缓存中 InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); // 3.检查InjectionMetadata是否需要刷新(为空或者class变了) if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { // 4.加锁后,再次从缓存中获取beanName对应的InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); // 5.加锁后,再次检查InjectionMetadata是否需要刷新 if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { // 6.如果需要刷新,并且metadata不为空,则先移除 metadata.clear(pvs); } try { // 7.解析@Autowired注解的信息,生成元数据(包含clazz和clazz里解析到的注入的元素, // 这里的元素包括AutowiredFieldElement和AutowiredMethodElement) metadata = buildAutowiringMetadata(clazz); // 8.将解析的元数据放到injectionMetadataCache缓存,以备复用,每一个类只解析一次 this.injectionMetadataCache.put(cacheKey, metadata); } catch (NoClassDefFoundError err) { throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + "] for autowiring metadata: could not find class that it depends on", err); } } } } return metadata; }
7.解析 @Autowired 注解的信息,生成元数据,见代码块3详解。
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { // 1.用于存放所有解析到的注入的元素的变量 LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>(); Class<?> targetClass = clazz; // 2.循环遍历 do { // 2.1 定义存放当前循环的Class注入的元素(有序) final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>(); // 2.2 如果targetClass的属性上有@Autowired注解,则用工具类获取注解信息 ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { // 2.2.1 获取field上的@Autowired注解信息 AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) { // 2.2.2 校验field是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的field if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static fields: " + field); } return; } // 2.2.3 获取@Autowired注解的required的属性值(required:值为true时,如果没有找到bean时,自动装配应该失败;false则不会) boolean required = determineRequiredStatus(ann); // 2.2.4 将field、required封装成AutowiredFieldElement,添加到currElements currElements.add(new AutowiredFieldElement(field, required)); } } }); // 2.3 如果targetClass的方法上有@Autowired注解,则用工具类获取注解信息 ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { // 2.3.1 找到桥接方法 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); // 2.3.2 判断方法的可见性,如果不可见则直接返回 if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } // 2.3.3 获取method上的@Autowired注解信息 AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { // 2.3.4 校验method是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的method if (Modifier.isStatic(method.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static methods: " + method); } return; } // 2.3.5 @Autowired注解标识在方法上的目的就是将容器内的Bean注入到方法的参数中,没有参数就违背了初衷 if (method.getParameterTypes().length == 0) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation should only be used on methods with parameters: " + method); } } // 2.3.6 获取@Autowired注解的required的属性值 boolean required = determineRequiredStatus(ann); // 2.3.7 获取method的属性描述器 PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); // 2.3.8 将method、required、pd封装成AutowiredMethodElement,添加到currElements currElements.add(new AutowiredMethodElement(method, required, pd)); } } }); // 2.4 将本次循环获取到的注解信息添加到elements elements.addAll(0, currElements); // 2.5 在解析完targetClass之后,递归解析父类,将所有的@Autowired的属性和方法收集起来,且类的层级越高其属性会被越优先注入 targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); // 2.6 递归解析targetClass父类(直至父类为Object结束) // 2.7 将clazz和解析到的注入的元素封装成InjectionMetadata return new InjectionMetadata(clazz, elements); }
2.2.1 获取 field 上的@Autowired 注解信息、2.3.3 获取 method 上的@Autowired 注解信息,见代码块1详解。
public void checkConfigMembers(RootBeanDefinition beanDefinition) { Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size()); // 1.遍历检查所有要注入的元素 for (InjectedElement element : this.injectedElements) { Member member = element.getMember(); // 2.如果beanDefinition的externallyManagedConfigMembers属性不包含该member if (!beanDefinition.isExternallyManagedConfigMember(member)) { // 3.将该member添加到beanDefinition的externallyManagedConfigMembers属性 beanDefinition.registerExternallyManagedConfigMember(member); // 4.并将element添加到checkedElements checkedElements.add(element); if (logger.isDebugEnabled()) { logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element); } } } // 5.赋值给checkedElements(检查过的元素) this.checkedElements = checkedElements; }
至此,使用@Autowire 修饰的方法和属性的相关元数据信息都已经放到 injectionMetadataCache 缓存中,用于后续使用。
2.postProcessPropertyValues 方法介绍
postProcessPropertyValues 被定义在 InstantiationAwareBeanPostProcessor接口中,该方法的主要作用是:将属性值应用于给定 bean 之前对给定属性值进行后置处理。
在AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行自动注入,将依赖的 bean 赋值给对应的属性。
在 Spring IoC 的过程中,调用的入口在:Spring IoC:createBean详解(下)中的代码块4中的7.1.1,下面介绍下postProcessPropertyValues 方法。
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
查看该方法的上下文,请参考:Spring IoC:createBean详解(下)中的代码块4中的7.1.1。
@Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { // 1.在指定Bean中查找使用@Autowire注解的元数据 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 2.InjectionMetadata: 执行inject()方法,开始执行属性注入或方法注入 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; }
1.在指定 bean 中查找使用 @Autowire 注解的元数据,见代码块2详解,这边会直接从缓存中拿到之前已经解析好的数据。
2.执行 inject() 方法,开始执行属性注入或方法注入,见代码块5详解。
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable { // 1.如果checkedElements存在,则使用checkedElements,否则使用injectedElements Collection<InjectedElement> elementsToIterate = (this.checkedElements != null ? this.checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { boolean debug = logger.isDebugEnabled(); for (InjectedElement element : elementsToIterate) { if (debug) { logger.debug("Processing injected element of bean '" + beanName + "': " + element); } // 2.解析@Autowired注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement, // 这两个类继承InjectionMetadata.InjectedElement,各自重写了inject方法。 element.inject(target, beanName, pvs); } } }
2.解析 @Autowired 注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement,这两个类继承InjectionMetadata.InjectedElement,各自重写了inject 方法。对于属性注入来说,会走到 AutowiredFieldElement 中的inject 方法,见代码块6详解。
代码块6:AutowiredFieldElement#inject
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { // 1.拿到该元数据的属性值 Field field = (Field) this.member; Object value; // 2.如果缓存中已经存在,则直接从缓存中解析属性 if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { // 3.将field封装成DependencyDescriptor DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { // 4.解析当前属性所匹配的bean实例,并把解析到的bean实例的beanName存储在autowiredBeanNames中 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { // 5.value不为空或者required为true if (value != null || this.required) { // 6.如果属性依赖注入的bean不止一个(Array,Collection,Map),缓存cachedFieldValue放的是DependencyDescriptor this.cachedFieldValue = desc; // 7.注册依赖关系到缓存(beanName 依赖 autowiredBeanNames) registerDependentBeans(beanName, autowiredBeanNames); // 8.如果属性依赖注入的bean只有一个(正常都是一个) if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName)) { // @Autowired标识属性类型和Bean的类型要匹配,因此Array,Collection,Map类型的属性不支持缓存属性Bean名称 // 9.检查autowiredBeanName对应的bean的类型是否为field的类型 if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { // 10.将该属性解析到的bean的信息封装成ShortcutDependencyDescriptor, // 以便之后可以通过getBean方法来快速拿到bean实例 this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } } else { this.cachedFieldValue = null; } // 11.缓存标识设为true this.cached = true; } } } if (value != null) { // 12.设置字段访问性 ReflectionUtils.makeAccessible(field); // 13.通过反射为属性赋值,将解析出来的bean实例赋值给field field.set(bean, value); } }
4.解析当前属性所匹配的 bean 实例,并把解析到的 bean 实例的beanName 存储在 autowiredBeanNames 中,见Spring IoC:createBean详解(上)中代码块9详解。
7.注册依赖关系到缓存(beanName 依赖 autowiredBeanNames),见代码块7详解。
13.通过反射为属性赋值,将解析出来的 bean 实例赋值给 field,至此,@Autowire 修饰的 bean 就被注入进来了。
private void registerDependentBeans(String beanName, Set<String> autowiredBeanNames) { if (beanName != null) { // 1.遍历所有autowiredBeanNames for (String autowiredBeanName : autowiredBeanNames) { if (this.beanFactory.containsBean(autowiredBeanName)) { // 2.如果autowiredBeanName在BeanFactory中存在,则注册依赖关系到缓存(beanName 依赖 autowiredBeanName) this.beanFactory.registerDependentBean(autowiredBeanName, beanName); } if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'"); } } } }
2.如果 autowiredBeanName 在 BeanFactory 中存在,则注册依赖关系到缓存(beanName 依赖 autowiredBeanName),见Spring IoC:getBean详解中代码块7详解。
本文简单的介绍了 @Autowire 常见的用法,并对 Spring IoC 构建过程@Autowire 注解相关的方法进行了解析。这些方法如果单独看可能无法很好的理解 @Autowire 注解,建议结合Spring IoC:createBean详解(上)和Spring IoC:createBean详解(下)一起阅读,以便更好的理解 @Autowire 注解的原理。