Spring

Spring立志全方面的简化java开发,主要采取了四个关键策略:

  1. 基于POJO的轻量级和最小侵入性编程
  2. 通过以来主图和面向接口松藕合
  3. 基于切面和惯性进行声明式编程
  4. 通过切面和模板减少样板式代码

主要通过:面向Bean,依赖注入以及面向切面这三种方式来实现的

 

BeanFactory接口,它是工厂设计模式得到实现,允许通过名称创建和检索对象。BeanFactory也可以管理对象间的关系。

BeanFactory支持两个对象模型

  1. 单例:模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索,Sigleton是默认的也是最常用的对象模型。对于无状态服务对象很理想
  2. 原型:模型确保每次检索都会创建新的对象。在每个用户都需要自己的对象时,原型模式最适合

Bean工厂的概念是Spring作为IOC容器的基础。IOC则将处理事情的责任从应用程序代码转换到了框架

 

AOP,面向切面编程,一种编程思想

AOP编程的常用场景有:Authentication 权限认证,Logging日志,Transctions Manage事务,Lazy Loading 懒加载,Context Process上下文处理,Error Handler错误跟踪(异常捕获机制),Cache缓存

 

Spring Framework 5 Runtime

 

 

Spring 5 包结构 以及依赖关系

 

 

 

 ListableBeanFactory主要是用来包装List,Array,Map类似这种集合的关系的BeanFactory

 HierarchicalBeanFactory用来初始化类与类之间具有层次关系的Bean

 AutowireCapableBeanFactory针对能够自动注入的生成Bean

BeanFactory的继承关系简图

 

 

 

ClassPathXmlApplicationContext是Spring项目的唯一入口,查看他的类图关系,可以发现他最终继承的源头就有BeanFactory

spring BeanFactory的基本工作流程:定位,加载,注册

所有的东西通过访问器访问进来以后都会变成一个东西:BeanDefinition,它就是装饰器模式的体现,体现了覆盖,扩展

 

资源定位是交给reader来实现完成

Context是入口

定位    用的  Reader 结尾的

加载     BeanDefinition保存类信息,包括OOP关系

注册     Factory,Context就是把用户所定义的Bean放到IOC容器中(Map)

Spring容器初始化就是这三个过程:定位,加载,注册,定位资源位置,加载资源内容,转换成BeanDefinition,注册,把Definition中的内容写入到Map中,也就是Context和xxFactory

 

    public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

初始化最核心的方法就是refresh(),把所有的Bean重新构造一遍

围绕Bean展开

    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
       //创建IOC容器 DefaultListableBeanFactory beanFactory
= createBeanFactory(); beanFactory.setSerializationId(getId());
       //对Ioc容器进行定制化,如设置启动参数,开启注解的自动配置等 customizeBeanFactory(beanFactory);
       //调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类只定义了抽象的loadBeanDefinition loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }

refreah()方法点进去会会看到

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        return getBeanFactory();
    }

refreshBeanFactory最终调用的就是DefaultListableBeanFactory的方法,也就是前面类图所描述最终实现是在DefaultListableBeanFactory中

 

 

IOC的本质就是个容器,

以下就是注册步骤的最终类DefaultListableBeanFactory的IOC容器(XML配置版)

 

 

 源码中抛出异常一般是在加载配置文件出错的时候,解析类出错的时候,初始化抛出不可预知异常的时候,以上都会导致IOC容器初始化终止,终止后就会去调用以下两个方法

 

 

 

依赖注入

Spring中的对象,默认是单例的,scope single

Spring中的对象init-lazy默认是false,如果你设置init-lazy为true,那么就只有在getBean的时候才会去实例化,才会去注入。

依赖注入的入口AbstractApplicationContext的getBean

 

 

BeanDefinition相当于是保存在内存中的配置文件,保存了所有的跟类属性相关信息,依赖注入就是把definition的信息读取出来,利用反射机制或者代理机制创建对象,新创建的对象,不会放到我们印象中的IOC容器中,它会存入到另外一个cache容器

Wrapper对原生对象的包装,通过构造方法存储原始对象,放入cache的只是Wrpper

这样做是为了减少代码侵入,能够在原生的基础之上,再进行扩展,监听器,回调函数,标记信息等

posted @ 2020-01-08 12:53  MonsterZL  阅读(332)  评论(0编辑  收藏  举报