Spring
Spring立志全方面的简化java开发,主要采取了四个关键策略:
- 基于POJO的轻量级和最小侵入性编程
- 通过以来主图和面向接口松藕合
- 基于切面和惯性进行声明式编程
- 通过切面和模板减少样板式代码
主要通过:面向Bean,依赖注入以及面向切面这三种方式来实现的
BeanFactory接口,它是工厂设计模式得到实现,允许通过名称创建和检索对象。BeanFactory也可以管理对象间的关系。
BeanFactory支持两个对象模型
- 单例:模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索,Sigleton是默认的也是最常用的对象模型。对于无状态服务对象很理想
- 原型:模型确保每次检索都会创建新的对象。在每个用户都需要自己的对象时,原型模式最适合
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
这样做是为了减少代码侵入,能够在原生的基础之上,再进行扩展,监听器,回调函数,标记信息等