本文主要是介绍揭密springboot自动装配(5)--ioc及@Autowired注解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
@Autowired 注解的bean什么时候实例化给它?
我们直接从AbstractAutowireCapableBeanFactory.doCreateBean开始,这个方法从上一章内容可得知是创建实例化对象然后放入三级缓存的singletonFactories里面,我们接着这个方法继续深究
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// 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;}}// 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);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
这里可以看到bean实例化之后放入三级缓存接着就会进入populateBean方法进行判断该实例化对象是否有@Autowired注解,有的话会进行@Autowired的对应的bean的获取或创建,废话不多说,直接看代码:下面populateBean部分关键代码
AbstractAutowireCapableBeanFactory.populateBean方法我们看如图,遍历所有beanPostProcessors
这里的beanPostProcessors是在AbstractApplicationContext.refresh方法里registerBeanPostProcessors(beanFactory);放进去的,里面有对应的AutowiredAnnotationBeanPostProcessor,这个就是专门处理@Autowired注解的
接着调用PropertyValues pvsToUse = (AutowiredAnnotationBeanPostProcessor)ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
这个方法里面可看到findAutowiringMetadata进行查询所有注解信息,可以看到拿到了usera这个属性
private com.example.demo.service.UserA com.example.demo.service.UserB.usera
我们进入AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata
接着AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata
AutowiredAnnotationBeanPostProcessor.findAutowiredAnnotation
this.autowiredAnnotationTypes这里面放的就是在AbstractApplicationContext.refresh方法里registerBeanPostProcessors(beanFactory)构造AutowiredAnnotationBeanPostProcessor时放入的@Autowired
返回这里:
然后调用metadata.inject(bean, beanName, pvs)进行对应属性usera初始化,继续往里走
AutowiredAnnotationBeanPostProcessor.inject()
DefaultListableBeanFactory.resolveDependency()
DefaultListableBeanFactory.doResolveDependency(),该方法里面继续调用DependencyDescriptor.resolveCandidate
DependencyDescriptor.resolveCandidate到这个方法里面就会发现一个熟悉的东西AbstractBeanFactory.getBean(beanName)
这不就是上章提到的获取bean嘛
调用这里将会进行对象获取如果获取不到就接着userA实例化,这就是一个递归
顺带提一下上节提到的三级缓存解决依赖注解的问题,从这里我们就可以看到,bean实例化时候将进入三级缓存,然后接着一系列操作看实例化的bean是否里面有@Autowired这样的注解,有的话接着对应属性的bean实例化,没有的话就将三级缓存的bean 放入一级缓存中
我们创建往userA之后接着回到AutowiredAnnotationBeanPostProcessor.inject()方法,最后将创建好的bean放入对应field里面完成@Autowired注解的属性的实例化
这篇关于揭密springboot自动装配(5)--ioc及@Autowired注解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!