Spring源码(四):注解的收集与依赖注入、initializeBean、Bean的销毁

一、收集注解

        实例化Bean只是在堆内存划了一片空间,Bean中带有@Autowired注解的属性是没有值的。在上一篇提到的doCreateBean里,applyMergedBeanDefinitionPostProcessors中MergedBeanDefinitionPostProcessor的实现类会收集各种注解,有CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、等。
在这里插入图片描述

        CommonAnnotationBeanPostProcessor支持@PostConstruct,@PreDestroy,@Resource注解的收集。
        AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解的收集。
        举例说明@Autowired注解的收集,其他的注解收集与之类似。在AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition的findAutowiringMetadatametadata = buildAutowiringMetadata(clazz);收集带有@Autowired的字段和方法。先收集到容器里,再把容器和Class封装成InjectionMetadata,放到缓存injectionMetadataCache中后返回。
在这里插入图片描述

二、依赖注入

在这里插入图片描述
        populateBean中支持了@Autowired依赖注入过程。首先看实现了InstantiationAwareBeanPostProcessor接口的调用,在postProcessAfterInstantiation方法中返回false可以让所有类都不能依赖注入。当然,也可以在方法中写逻辑判断,实现部分类依赖注入。
在这里插入图片描述
        接着从这里可以看到依赖注入过程。
在这里插入图片描述
        来到AutowiredAnnotationBeanPostProcessor.postProcessProperties,首先从缓存中拿到InjectionMetadata对象(InjectionMetadata是在applyMergedBeanDefinitionPostProcessors中加入到缓存的)。
在这里插入图片描述
        AutowiredAnnotationBeanPostProcessor.inject的beanFactory.resolveDependency会触发依赖注入属性的getBean操作,这个里面涉及到各种类型的判断,不用深入的去看。
        最后,通过反射完成属性和方法的依赖注入。
在这里插入图片描述
在这里插入图片描述

三、initializeBean

        doCreateBean的initializeBean是实例化和依赖注入完以后的调用。

1. 调用Aware接口

        在invokeAwareMethods中可以看到,这个里面是各种Aware接口的调用。比如说,BeanNameAware.setBeanName可以拿到beanName,BeanFactoryAware.setBeanFactory可以拿到beanFactory对象。
在这里插入图片描述

2. 对类中某些特殊方法的调用,比如@PostConstruct,Aware接口

        来到applyBeanPostProcessorsBeforeInitialization,这里循环调用BeanPostProcessor的postProcessBeforeInitialization方法。下面举一些例子。
        在InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization中看到,可以从缓存中取出带有@PostConstruct的方法,反射调用方法。
在这里插入图片描述
        在ApplicationContextAwareProcessor.postProcessBeforeInitialization中是对EnvironmentAware、ApplicationEventPublisherAware等Aware接口的支撑。
在这里插入图片描述
        在ImportAwareBeanPostProcessor.postProcessBeforeInitialization中可以看到,在ImportAware的实现类的setImportMetadata方法中调用AnnotationMetadata.getAnnotations()能拿到import了这个Bean的类的注解。
在这里插入图片描述
        例如,ImportBean通过@import注解import了AwareBean,如果AwareBean实现了ImportAware接口,就可以在setImportMetadata方法中通过AnnotationMetadata.getAnnotations()拿到ImportBean的所有注解。
在这里插入图片描述
在这里插入图片描述

3. InitializingBean接口、init-method属性调用

        接着来到invokeInitMethods,这里调用了实现InitializingBean接口的afterPropertiesSet方法。
在这里插入图片描述
        下面是对xml中init-method方法的调用。获取init-method属性中的方法,判断方法名称不为afterPropertiesSet,最后反射调用方法。
在这里插入图片描述
        从这里可以看到,带有@PostConstruct的方法、实现InitializingBean接口的afterPropertiesSet方法、init-method配置的方法,这3类方法的作用都是一样的,都是在Bean实例化完成后做一些操作。区别是调用的时序不一样,带有@PostConstruct的方法最开始执行,然后是InitializingBean接口的afterPropertiesSet方法,最后是init-method配置的方法。

4. 另外一些BeanPostProcessor的调用

        从applyBeanPostProcessorsAfterInitialization进入,和applyBeanPostProcessorsBeforeInitialization一样,这里也是循环BeanPostProcessor,调用postProcessAfterInitialization方法。例如,会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值