作者: | 来源:互联网 | 2023-09-14 13:58
使用classpathXmlApplicationContext的方式加载配置文件第一步:拿到xml配置文件第二步:①创建beanFactory②xml解析,包含bean、impo
使用classpathXmlApplicationContext的方式加载配置文件
第一步:拿到xml配置文件
第二步:①创建beanFactory②xml解析,包含bean、import,自定义标签
自定义标签解析流程:
a、根据当前解析标签的头信息找到对应的namespaceUri
b、加载spring所以jar中的spring.handlers文件。并建立映射关系
c、根据namespaceUri从映射关系中找到对应的实现了NamespaceHandler接口的类
d、调用类的init方法,init方法是注册了各种自定义标签的解析类
e、根据namespaceUri找到对应的解析类,然后调用paser方法完成标签解析
第三步:把解析出来的xml标签封装成BeanDefinition(beanDefintion是在Spring在实例化过程中,根据beandedination对象里面的属性信息来进行实例化bean的操作)对象如果是通过注解解析获取的BeanDefinition对象里面会有一个metadataReader对象,这个metadataReader包含了一个类的所有的基本信息,然后通过metadataReader对BeanDefinition的属性进行设值,如果项目支持IOC、aop、Autowired、@bean等注解,则需创建相应的BeanDefinitionRegistryPostProcessor(后置处理器)的beanDefintion
第四步:上面创建了sprint实例化工厂的所有的beanDefintion,这部开始就是实例化bean了,
- 首先实例化所有实现了BeanDefinitionRegistryPostProcessor接口的beanDefintion
- 把实现了BeanPostProcessor接口的类实例化
第五部:finishBeanFactoryInitialization()
- 1、bean实例化过程
- 1、factoryMethod方式
- 2、有参构造方法方式(在实例化bean的过程中,会在class中找有没有Autowired注解,如果有,再次判断注解的属性是否为class类型,如果是,就触发这个对象的getBean操作)
- 3、无参构造方法方式
- 此步骤完成后,已经在堆空间分配内存,还不完整,不可用,没有进行依赖注入
- 2、收集信息
- CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解
- 1、扫描类里面的属性或者方法
* 2、判断属性或者方法上面是否有@PostConstruct @PreDestroy @Resource注解
* 3、如果有注解的属性或者方法,包装成一个类InjectionMetadata
- AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解,包装成一个类InjectionMetadata
- BeanPostProcessor接口的典型运用,这里要理解这个接口 //对类中注解的装配过程,对类进行依赖注入进行装配收集
- 3、ioc 注解支持
- a、依赖注入:对上个步骤收的InjectionMetadata信息进行操作,
- 如果InjectionMetadata为属性,判断属性是否为class对象,如果是触发该对象的getBean操作,拿到实例化的value,反射赋值
- 如果InjectionMetadata为方法,判断方法的属性是否为class对象,如果是触发该对象的getBean操作,拿到实例化的value,反射赋值
- b、循环依赖:A、B两个对象互相有依赖注入,在A的实例化过程中,先进行构造方法初始化bean放进三级缓存后,进行IOC、di(populateBean()),发现有B的依赖注入,就触发了B的getBean操作,在B的实例化过程中,先进行构造方法初始化bean放进三级缓存后,进行IOC、di,发现有A的依赖注入,触发了A的getBean操作,这时从三级缓存中直接拿到了A的实例化对象,把A从三级缓存提升到二级缓存,返回,B的实例化完成,把B加入到一级缓存,并且从三级缓存中删除,这时回到了开始的A的实例化过程,拿到了B的实例化对象,A的实例化也完成。上述就是循环依赖的过程
-
- 4、BeanPostProcessor的执行
- 5、实例化bean后对初始化方法的调用
- 6、Aop的入口