面试中碰到面试官问:”Spring 注解是若是工做的?“,当前我一惊,完了这不触及到个人知识误区了吗?,还好我机智,灵机一动回了句:Spring 注解的工做流程倒尚未看到,可是我知道@Autowired
注解的工做流程,后面不用说了一顿巴拉,面试官都连连点头。java
面试中要活用转移话题,要避免回答 ”不知道“,要引导面试官掉入你擅长的技术,而后才有机会教他做人。面试
@Autowired 注解的主要功能就是完成自动注入,使用也很是简单(Spring都安排好了),可是要想知道 @Autowired 注解的内部现实,就须要看一下Spring源码了。接下来一步步的解剖 @Autowired 的实现原理,首先理一下与 @Autowired 注解相关的类,而后一步步的跟踪源码,直到理解 @Autowired 的原理。缓存
AutowiredAnnotationBeanPostProcessor
是实现 @Autowired 功能的主要类,它有一些方法是会用解析 @Autowired 注解并实现自动注入的功能,下面是它的继承图:架构
从上图能够发现 AutowiredAnnotationBeanPostProcessor 最上层是 BeanPostProcessor
是一个后处理器,固然除了后处理器外中间还有InstantiationAwareBeanPostProcessor
和MergedBeanDefinitionPostProcessor
:app
postProcessBeforeInstantiation方法ide
在Bean实例化以前调用,能够返回一个Bean实例,默认返回null
。post
@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null;}
postProcessAfterInstantiation方法学习
在Bean建立完成后,设置属性以前调用。ui
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true;}
postProcessProperties方法this
@Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null;}
Bean建立完后,设置属性以前调用
先记住 InstantiationAwareBeanPostProcessor 接口,后面会跟踪调用它的地方,就很容易理解了。
MergedBeanDefinitionPostProcessor
也是一个继承 BeanPostProcessor
接口的后处理器,它的主要做用就是能够处理操做BeanDefinition
对象,因为Bean的实例化是经过 BeanDefinition 的, 经过操做BeanDefinition ,这样能够使Bean的实例化时发生一些变化。
MergedBeanDefinitionPostProcessor 只有两个方法
postProcessMergedBeanDefinition方法
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
Bean的BeanDefinition 被合并后调用此方法。
resetBeanDefinition
default void resetBeanDefinition(String beanName) {}
当一个BeanDefinition被重置后调用 。
AutowireCapableBeanFactory
继承自BeanFactory
,除了提供基础的Bean操做外,从接口的名字就能够推断出的它还有自动注入
的能力。AutowireCapableBeanFactory 提供四种注入模型:
AutowireCapableBeanFactory 接口有很多方法,但大部分都是跟自动注入的相关。@Autowired 的主要功能就是在Bean实例化后,为其设置属性,因此在 AutowireCapableBeanFactory 接口有一个 createBean
方法,用于建立Bean并设置Bean的属性:
<T> T createBean(Class<T> beanClass) throws BeansException;
createBean
方法,它的调用时机是建立Bean的时候,稍后会说到它的调用时机。
AbstractAutowireCapableBeanFactory 继承 AbstractBeanFactory
并实现了AutowireCapableBeanFactory
接口,因此它也实现了AutowireCapableBeanFactory
中的createBean
方法。
public <T> T createBean(Class<T> beanClass) throws BeansException { // Use prototype bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(beanClass); bd.setScope(SCOPE_PROTOTYPE); bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader()); return (T) createBean(beanClass.getName(), bd, null);}
经过了解Bean建立的生命周期,才能够将上面与 @Autowired 相关的类串起来,首先这里不会过多的介绍Bean的建立细节,只关注自动注入相关的代码。
Spring中默认的Bean都是懒加载的,因此一个Bean的建立会从调用getBean
方法开始,若是不考虑缓存、上层容器的状况,Bean的建立会通过如下方法:
以上流程中的getBean
和doGetBean
很少做说明了, 重点关注createBean
前面提到AbstractAutowireCapableBeanFactory.createBean
方法,因此说你在调用getBean
方法获取Bean的实例时,若是这个Bean实例尚未被建立,那么createBean
就会被调用。
经过简单的说明Bean建立的生命周期,就能找到 @Autowired 注解实现的入口,接下来再继续跟踪createBean
方法。
收集注入元信息的步骤的,其实就是调用AutowiredAnnotationBeanPostProcessor
类方法来实现的。
如下是createBean
方法,在Bean建立以前调用postProcessBeforeInstantiation
的地方。为是阅读方便省略了一些代码,大体的流程就是:
resolveBeforeInstantiation
方法,执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
方法postProcessBeforeInstantiation
返回Bean实例那么直接返回这个实例,若是返回nul 继续调用doCreateBean
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { ... try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { ... } ... Object beanInstance = doCreateBean(beanName, mbdToUse, args); ... ... } @Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
这里 AutowiredAnnotationBeanPostProcessor 的 postProcessBeforeInstantiation 的方法会被调用,因为AutowiredAnnotationBeanPostProcessor 并无重写这个方法,因此什么都不作。
上面说过 postProcessBeforeInstantiation 方法返回 null 的话会继续执行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) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } ... populateBean(beanName, mbd, instanceWrapper); ...
在 doCreateBean 方法中,会调用调用applyMergedBeanDefinitionPostProcessors
方法:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } }
MergedBeanDefinitionPostProcessor
接口上面提到到的,AutowiredAnnotationBeanPostProcessor 实现了这个接口因此直接进入到 AutowiredAnnotationBeanPostProcessor 中的 postProcessMergedBeanDefinition
方法:
@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); }
接着继续进入到findAutowiringMetadata
,findAutowiringMetadata 会调用buildAutowiringMetadata
方法建立注入元数据,而后将元数据缓存到injectionMetadataCache
属性中:
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)) { ... metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }
仔细查看buildAutowiringMetadata
方法的实现,它会反射类的方法和属性,同时还会向上查找父类,而后生成InjectionMetadata
。
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { 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<>(); 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); 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); 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); }
收集注入元数据过程,首先调用AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
方法,而后调用findAutowiringMetadata
方法查找元数据,若是找到相应类的注入元数据 ,就会调用buildAutowiringMetadata
方法建立InjectionMetadata
,最后将新建立的注入元数据保存在injectionMetadataCache
缓存起来。
收信完注入元数据后,Bean的属性仍是没有注入的,还须要将执行属性注入。仍是在doCreateBean
方法中,收集完注入元数据后,紧接着会调用populateBean
:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 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; } } } }
能够看到在populateBean
中会调用InstantiationAwareBeanPostProcessor.postProcessProperties
方法,因为已经知道 AutowiredAnnotationBeanPostProcessor 是实现 InstantiationAwareBeanPostProcessor 的,因此能够直接查看实现方法:
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); } return pvs; }
postProcessProperties
就很简单的,查找 InjectMetadata,而后调用 InjectMetadata.inject
方法。到这里其实就已经知道@Autowire
的实现机制了,接下来就是根据InjectionMetadata
中的信息实现属性注入了。
若是须要深刻研究的话,有兴趣的还能够继续往下看。
本文大体讲解了 @Autowire 相关的类与实现的机制,@Autowire 注解的实现主要是理解AutowiredAnnotationBeanPostProcessor
类,还有收集注入元数据、设置注入属性的调用时机。
经过查看AutowiredAnnotationBeanPostProcessor
类源码,相信你也能够自定义注入功能。
本人知识水平有限,若有错误,谢谢你们指正。
欢迎关注个人公众号:架构文摘,得到独家整理120G的免费学习资源助力你的架构师学习之路!公众号后台回复
arch028
获取资料: