zoukankan      html  css  js  c++  java
  • [Java] Spring 源码分析

    IOC(Inverse of Control)控制反转

    • 依赖对象的获得被反转了,由自己创建变为从IOC容器获取
    • 优点
      • 代码更简介,不需要new对象
      • 面向接口编程,使用者与具体类解耦,易扩展
      • 方便进行AOP编程,在IOC容器中进行AOP
    • 功能:创建、管理类的实例,向使用者提供实例
    • 工厂模式应用,IOC容器也称为Bean工厂
    • Bean:组件,类的对象
    • Bean工厂设计
      • 接口:对外提供Bean实例,getBean()
      • 参数:创建产品的类
      • 返回值:各种类型Bean,Object
    • Bean定义:告诉Bean工厂如何创建某类Bean,可根据获取对象方式扩充
      • new构造方法
      • 静态工厂方法
      • 成员工厂方法
    • Bean定义注册接口
      • 注册、获取Bean定义

       

      

       

    默认Bean工厂实现

    • 实现定义信息注册
      • 用Map存储BeanName和BeanDefinition
      • 重名的处理
    • 实现Bean工厂getBean
      • 通过反射创建对象
      • BeanFactory和FactoryBean
    • 实现初始化方法执行
      • doInit(),反射调用初始化方法
    • 实现单例
      • 通过名字取实例,用Map保存
      • 有则返回,无则创建
      • 保证单例,加锁+双重检查(DCL)
      • volatile:保证变量可见性,防止指令重排
    • 实现别名
      • Map<alias,name>
    • 按照Type获取Bean
      • 注册Bean定义时,在registerBeanDefinition()中建立映射关系
      • BeanDefination获取Class:在所有Bean定义注册完后,实例化单例Bean前
      • DefaultBeanFactory中增加buildTypeMap()
      • 遍历name对应的Bean定义,找出Primary,获取实例,没有Primary或有多个则抛异常
    • 实现容器关闭时执行单例的销毁方法
      • Bean生命周期
        • 单例Bean:容器关闭时销毁
        • 原型Bean:由使用者管理
      • 程序结束
        • 自然结束
        • 主动关停  

     

    DI(Dependency injection)依赖注入

    • 哪些地方有依赖
      • 构造参数依赖
      • 属性依赖
    • 依赖注入本质
      • 给构造参数赋值
      • 给属性赋值
    • 直接值的类型
      • 基本数据类型值,String
      • 数组,集合,Map
    • 如何告诉Bean工厂该给入什么构造参数值,即如何定义参数依赖
      • 用LIst存储,按参数顺序放入
      • BeanReference:说明Bean依赖,即依赖哪个Bean,可以按name或Type依赖
      • 如何定义属性依赖  

    构造参数依赖实现

    • BeanFactory中实现构造参数依赖注入
    • 静态工厂方法、工厂方法中参数依赖处理一样
    • 在BeanDefination中增加方法,缓存原型Bean的构造方法或工厂方法
    • 循环依赖
      • 在doGetBean()中加入一个正在创建Bean的记录,每个Bean开始创建时加入该记录中
      • getBean时先看bean是否在记录中,如果是则构成了循环依赖,抛出异常
      • 创建完后从记录中移除
      • 并发问题
        • a和依赖a的b同时创建,报错
        • 线程隔离
        • ThreadLocal<Set<String>> buildingBeanRecorder

    属性依赖实现

    • 某个属性依赖什么
      • 某个值
    • 如何描述一个属性依赖
      • 属性名、值,定义一个类表示两个值
    • 多个属性依赖怎么存放
      • LIst
    • 属性值情况和构造函数参数值一样吗
      • 一样,直接值或Bean依赖 
    • DefaultBeanFactory中实现属性依赖
    • 何时进行属性依赖注入
      • Bean示例创建好后,执行初始化方法前
    • 属性依赖可以循环吗
      • 自己new可以,IOC容器中不可以  

    AOP(面向切面)依赖注入

    • 定义
      • 在不改变代码的情况下,对类方法进行功能增强
      • 在框架中向用户提供AOP功能,通过AOP对类方法进行功能增强

    • 方式
      • 编译时增强/运行时增强
      • 动态代理
    • 术语
      • Advice(通知):增强的功能(用户提供)
      • Join Points(连接点):可选的方法点(用户提供)
      • Pointcut(切入点):选择切入的方法点(用户提供)
      • Aspect(切面):选择的方法点+增强的功能
      • Introduction(引入):添加新的方法、属性到已存在的类中
      • Weaving(织入):不改原类的代码,加入功能增强
    • Advice
      • 用户提供
      • 变化:不同增强需求,实现逻辑不同
      • 时机:可选择在方法功能前、后、异常时进行功能增强
        • Before(前置)
        • After(后置)
        • AfterReturn(后置)
        • Around(环绕)
        • 异常处理
      • 多重:同一个切入点可有多重增强

    • Pointcut
      • 用户性:用户指定
      • 变化:灵活
      • 多点:用户可选择多个点进行增强
      • 描述信息:xx类的xx方法(方法签名)
      • 表达式:决定是否要对xx类的xx方法进行增强
      • 设计
        • 切点有什么属性?定义表达式
        • 对外提供什么行为?方法
        • 用来做什么?对类、方法进行匹配,切点提供匹配类/方法的行为

    • Weaving
      • 无侵入性,不改原类代码
      • 在框架中实现
      • 将用户提供的增强功能加到指定的方法上
      • 创建bean实例时,bean初始化后,进行增强,返回代理对象创建的实例
      • 一次写好BeanFactory后,不改代码实现灵活扩展
      • 在各节点加入扩展点,加入注册机制
      • 观察者模式(监听模式),6个扩展点,6个主题/观察者
      • 如何判断Bean实例是否要增强
        • 获取bean的类及所有方法
        • 遍历Advisor,取advisor中的pointcut来匹配类,方法
      • 动态代理的实现方式
      • 如有增强的advice,用责任链模式执行增强

    • 面向接口
      • 用户(开发人员)通过接口实现不同逻辑

    Bean定义配置化

    • 对象少时,可通过new,set
    • 对象多时,通过xml配置bean,或通过注解实现
    • 解析xml/注解进行bean定义
    • xml方式
      • 定义xml规范
      • 解析xml,完成bean定义注册
    • 注解方式
      • 定义注解,哪些类/属性需要依赖注入
      • 代码扫描,解析注解,完成bean定义注册 
      • 结合反射完成功能
      • 定义
        • @Component:类要不要配置为bean
        • @Scope
        • @Primary
        • @Bean:通过工厂方法创建bean
        • @PostConstruct、@PreDestroy:初始化、销毁方法
        • @Autowired、@Value:构造参数、属性依赖
        • @Qualifier

    ApplicationContext

    • 获取bean定义,扫描包,注册bean
    • 外观模式(门面模式),为框架定义一个更简单的统一使用页面

    手写Spring

    • 初始化阶段
      • 加载配置文件
      • 扫描相关类
      • 实例化相关类
      • 实现依赖注入
      • 初始化HandlerMapping
    • 运行阶段
      • 通过url找到method
      • 提取request的参数
      • 提取method的形参列表
      • 给method的实参列表赋值
      • 反射调用method,返回结果

    常用类

    • ApplicationContext
      • 创建对象
      • 将对象缓存到IoC容器中(Map)
      • 执行依赖注入DI
    • BeanDefinition:配置文件封装(yml、properties、xml、json)
    • BeanDefinitionReader:读取配置信息(工具类)
    • BeanWrapper:Bean实例包装类
    • getbean()
      • 拿到BeanName的配置信息,即BeanConfiguration
      • 实例化对象
      • 将实例化后的对象封装成BeanWrapper
      • 将BeanWrapper缓存到IoC容器中
      • 完成依赖注入

    参考

    IOC

    https://blog.csdn.net/love_everybody/article/details/79836136

    Java反射技术——字段的获取

    https://blog.csdn.net/zlb824/article/details/7494300

    web.xml文件的作用及基本配置

    https://www.cnblogs.com/fnlingnzb-learner/p/6560774.html

    jetty安装

    https://www.jianshu.com/p/2412ccfb36e1

    IDEA+Tomcat+Maven

    https://blog.csdn.net/limshirley/article/details/86682364

    静态工厂方法和实例工厂方法

    https://www.cnblogs.com/yonyong/p/9405963.html

  • 相关阅读:
    InfoPath 发布表单到SharePoint库报错
    在log4net中控制nhibernate输出
    微信扫一扫(wx.scanQRCode)功能新手可能遇到的问题
    3.Zookeeper的安装和配置(集群模式)
    1.配置HDFS HA (高可用)
    2.Zookeeper工作原理(详细)
    1.Zookeeper 定义与工作原理
    js 获取元素的几种方法
    弹出层居中
    XUACompatible
  • 原文地址:https://www.cnblogs.com/cxc1357/p/13455834.html
Copyright © 2011-2022 走看看