Spring Core总结

Spring学习笔记

Spring的优势

  • ⽅便解耦,简化开发
    通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进⾏控制,避免硬编码所造成的
    过度程序耦合。⽤户也不必再为单例模式类、属性⽂件解析等这些很底层的需求编写代码,可以更
    专注于上层的应⽤。

  • AOP编程的⽀持
    通过Spring的AOP功能,⽅便进⾏⾯向切⾯的编程,许多不容易⽤传统OOP实现的功能可以通过
    AOP轻松应付。

  • 声明式事务的⽀持
    @Transactional
    可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式⽅式灵活的进⾏事务的管理,提⾼
    开发效率和质量。

  • ⽅便程序的测试
    可以⽤⾮容器依赖的编程⽅式进⾏⼏乎所有的测试⼯作,测试不再是昂贵的操作,⽽是随⼿可做的
    事情。

  • ⽅便集成各种优秀框架
    Spring可以降低各种框架的使⽤难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、
    Quartz等)的直接⽀持。

  • 降低JavaEE API的使⽤难度
    Spring对JavaEE API(如JDBC、JavaMail、远程调⽤等)进⾏了薄薄的封装层,使这些API的使⽤
    难度⼤为降低。

  • 源码是经典的 Java 学习范例
    Spring的源代码设计精妙、结构清晰、匠⼼独⽤,处处体现着⼤师对Java设计模式灵活运⽤以及对
    Java技术的⾼深造诣。它的源代码⽆意是Java技术的最佳实践的范例。

Spring IoC

bean的生命周期

bean的生命周期是指一个bean对象从创建到销毁的过程. bean不等于普通对象, 是里胡一个java对象只是bean的生命周期过程的一步,只有走完了流程, 才能称之为bean. 核心过程如下:

  1. 实例化bean: 主要通过反射技术实例化

  2. 设置对象属性(依赖注入)

  3. 处理Aware接口

    如果实现了xxxAware接口, 会将相关的xxxAware实例注入给bean

    如果实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法

    如果事项了BeanFactoryAware接口, 会调用它实现的setBeanFactory()方法, 传递的是Spring工厂

    如果实现了ApplicationContextAware接口, 会调用它实现的setApplicationContext()方法,传递的是Spring上下文

  4. BeanPostProcessor:

    如果实现了此接口,会调用 postProcessBeforeInitialization()方法

  5. InitializingBean与 init-method:

    实现bean初始化的一些逻辑

    如果配置了init-method,则会自动调用此方法,完成自定义初始化逻辑

  6. 如果实现了BeanPostProcessor接口,会调用 postProcessAfterInitialization()方法

  7. DisposableBean:

    当bean不需要使用时, 会经过清理阶段, 如果实现了此接口, 则会调用它实现的destroy()方法

  8. 最后,如果配置了destroy-method:则会自动调用此方法,完成自定义销毁逻辑

高级特性

lazy-Init 延迟加载

设置 lazy-init 为 true 或者注解 @Lazy 的 bean 将不会在 ApplicationContext 启动时提前被实例化,⽽是第⼀次向容器
通过 getBean 索取 bean 或者在 bean被其他立即实例化的bean引用时实例化的。

FactoryBean 和 BeanFactory

BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,
具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean

Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成
某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。

自定义FactoryBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
@Nullable
// 返回FactoryBean创建的Bean实例,如果isSingleton返回true,
//则该实例会放到Spring容器的单例对象缓存池中Map
T getObject() throws Exception;
@Nullable
// 返回FactoryBean创建的Bean类型
Class<?> getObjectType();
// 返回作⽤域是否单例
default boolean isSingleton() {
return true;
}
}

后置处理器

Spring提供了两种后处理bean的扩展接⼝, 分别为 BeanPostProcessor 和BeanFactoryPostProcessor,两者在使⽤上是有所区别的。⼯⼚初始化(BeanFactory)—> Bean, 对象在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理, 做⼀些事情在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处理做⼀些事情
注意:对象不⼀定是springbean,⽽springbean⼀定是个对象

自动装配

有五种自动装配方式, 可以用来知道Spring容器用自动装配方式来依赖注入:

  • no: 默认不进行自动装配, 通过显式设置ref属性来进行装配
  • byName: 通过参数名自动装配, Spring容器在配置文件中发现bean的autowire属性被设置成byName,止呕容器试图装配和该bean的属性具有相同名字的bean
  • byType: 通过参数类型自动装配, Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
  • constructor:这个方式类似于byType,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
  • autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。

SpringAOP及应用

AOP的实现

Spring 实现AOP思想使⽤的是动态代理技术
默认情况下,Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。当被代理对象没有实现
任何接⼝时,Spring会选择CGLIB。当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术,不过
我们可以通过配置的⽅式,让Spring强制使⽤CGLIB

Spring 声明式事务的⽀持

编程式事务:在业务代码中添加事务控制代码,这样的事务控制机制就叫做编程式事务
声明式事务:通过xml或者注解配置的⽅式达到事务控制的⽬的,叫做声明式事务

事务的四大特性

  • 原⼦性(Atomicity) 原⼦性是指事务是⼀个不可分割的⼯作单位,事务中的操作要么都发⽣,要么都
    不发⽣。从操作的⻆度来描述,事务中的各个操作要么都成功要么都失败

  • ⼀致性(Consistency)事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态。
    例如转账前A有1000,B有1000。转账后A+B也得是2000。
    ⼀致性是从数据的⻆度来说的,(1000,1000) (900,1100),不应该出现(900,1000)

  • 隔离性(Isolation)事务的隔离性是多个⽤户并发访问数据库时,数据库为每⼀个⽤户开启的事务,
    每个事务不能被其他事务的操作数据所⼲扰,多个并发事务之间要相互隔离。
    ⽐如:事务1给员⼯涨⼯资2000,但是事务1尚未被提交,员⼯发起事务2查询⼯资,发现⼯资涨了2000
    块钱,读到了事务1尚未提交的数据(脏读)

  • 持久性(Durability)持久性是指⼀个事务⼀旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发⽣故障
    也不应该对其有任何影响。

事务的隔离级别

  • Serializable(串⾏化):可避免脏读、不可重复读、虚读情况的发⽣。(串⾏化) 最⾼

  • Repeatable read(可重复读):可避免脏读、不可重复读情况的发⽣。(幻读有可能发⽣) 第⼆
    该机制下会对要update的⾏进⾏加锁

  • Read committed(读已提交):可避免脏读情况发⽣。不可重复读和幻读⼀定会发⽣。 第三

  • Read uncommitted(读未提交):最低级别,以上情况均⽆法保证。(读未提交) 最低

    事务隔离级别 脏读 不可重复度 幻读
    Read uncommitted(读未提交)
    Read committed(读已提交)
    Repeatable read(可重复读)
    Serializable(串行化)

Spring设计模式

  • 工厂设计模式: BeanFactory, ApplicationContext 通过工厂模式创建对象

  • 代理设计模式: SrpingAOP 用到了JDK动态代理和CGLIB动态代理

  • 单例设计模式: bean默认都是单例

  • 模板方法模式: jdbcTemplate, hibernateTemplate 等以Template结尾的对数据库操作的类,用到了模板设计模式

  • 包装器设计模式: 动态数据源的支持

  • 观察者设计模式: Spring时间驱动模型

  • 适配器模式: SpringAOP的增强或者通知(Advice)使用了适配器模式, SpringMVC也是用到了该模式适配Controller