zoukankan      html  css  js  c++  java
  • spring源码分析——依赖注入(set注入、构造器注入、Autowired注解注入)

      spring容器的核心IOC和Aop,其中ioc控制反转,就是spring容器帮助程序员创建对象以及维护对象之间的依赖关系,

    DI依赖注入就是其中非常重要的一环,我们平常使用比较多的就是set注入、构造器注入,使用@Autowired、@Resource注解注入等,

    下面我们就分析一下spring源码是怎么实现的。

    一:set注入

    准备环境:

    在spring-context.xml中配置student的bean信息

    	<bean id="student" class="com.hello.model.Student">
    		<property name="height" value="100"></property>
    		<property name="weight" value="300"></property>
    	</bean>
    

      

    运行结果:

     

     下面从源码来看一下set注入:

    在解析spring-context.xml的时候,解析bean元素,会解析到子元素property,这个部分在默认标签解析那节分析过,然后把属性值封装

    到MultablePropertyValues对象上,放到BeanDefinition对象上面缓存

    进入polulateBean方法中:

    从BeanDefinition对象中拿到PropertyValues属性:

    应用属性值:

     

     

     

     刚才我们使用的是set注入,直接注入的字符串,如果使用ref,注入对象,会如何处理?

    看一下下面标注的这行代码,根据原始值获取value值:

    如果是字符串类型,则直接获取字符串的值,上面的value=“100”,就是走到这里

    如果是引用类型,会走到如下分支代码:

    根据参数名称,到beanFactory容器中获取bean对象,其他的步骤和字符串的value一样

     二:构造器注入

    构造器注入的方式就是上一节分析的有参数构造器的创建过程,在实例化的过程中就实现了注入

    	<bean id="student" class="com.hello.model.Student">
    		<constructor-arg index="0" value="100"/>
    		<constructor-arg index="1" value="200"/>
    	</bean>
    

    运行结果:

     分析过程见上一节实例化对象的分析

    三:@Autowired注解注入依赖

    准备工作:

     运行结果:

    这里面有两个比较重要的对象AutowireAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor

    首先要埋点,创建BeanDefinition对象,然后注册到BeanDefinitionMaps缓存中,看一下ComponentScanBeanDefinitionParser类

    注册注解辅助相关组件:

    将AutowiredAnnotationBeanPostProcessor封装成BeanDefinition对象,注册到BeanDefinitionMaps缓存中

    注册完成后,就要实例化对象,实例化的动作实在refresh方法的registerBeanPostProcessors方法中完成的,这一步在之前分析BeanPostProcessor接口的时候已经分析过

    这一步完成后,AutowiredAnnotationBeanPostProcessor对象就被注册到了BeanPostProcessors集合中,以备后面拦截使用

     

    注册beanDefinition完成,实例化对象完成,下面就要看具体的拦截使用。

     我们来看一下搜集过程:

     

     搜集类上的注解信息:

    搜集字段和方法上的注解信息:

     

     因为我们的@Autowired注解是在属性上,所以我们看一下解析字段属性的代码块

     

    搜集到Cat cat 属性上面有Autowired注解信息

     到这里类clazz的注解属性信息搜集完毕,放入缓存中

    回到populateBean方法中,设置bean对象的属性

     

     从缓存中取出注解元数据信息:

    注入依赖对象:

    到容器singletonObjects缓存中查找或者实例化对象,然后反射实现对象注入

     

    寻找依赖:

     实例化依赖的bean对象,然后在上一步反射实现注入,到这里Autowired注解实现依赖注入的过程就结束了。

    总结:依赖注入是spring容器IOC能够实现的核心功能,spring容器帮助我们维护对象之间的关系。

    set注入:主要是在解析的时候property属性封装到BeanDefinition对象上,然后在pupulateBean设置属性的时候,

    从BeanDefinition的MultiPropertyValues中取出数据,然后通过反射设置到对象上,如果设置的值为bean,那么在解析的时候

    会用到一个runtimeRefence,然后在populateBean的时候再通过getBean实例化对象

    构造器注入,在创建对象的时候,从BeanDefinition的ConstructArgs中取出数据,反射寻找有参数构造器,然后创建对象实例

    @Autowired注解主要实现依赖于AutowiredAnnotationBeanPostProcesor,埋点,注册BeanDefinition,实例化,搜集注解信息,拦截根据属性getBean寻找bean对象,反射注入。

  • 相关阅读:
    C# .NET Socket封装
    Web页面实现后台数据处理进度与剩余时间的显示
    彻底解决“从客户端中检测到有潜在危险的Request.Form值”
    自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版
    Oracle导入导出命令
    Oracle创建用户、表空间并设置权限
    Web Service 和WCF的比较
    Win10下IIS配置图解、MVC项目发布图解、IIS添加网站图解
    图表控件MsChart使用demo
    Excel中的宏--VBA的简单例子
  • 原文地址:https://www.cnblogs.com/warrior4236/p/13216415.html
Copyright © 2011-2022 走看看