学习思路

首先要明确Spring是个什么东西,能帮我们做些什么事情,知道了这些然后做个简单的例子,这样就基本知道怎么使用Spring了。Spring核心是IoC容器,所以一定要透彻理解什么是IoC容器,以及如何配置及使用容器,其他所有技术都是基于容器实现的;理解好IoC后,接下来是面向切面编程,首先还是明确概念,基本配置,最后是实现原理,接下来就是数据库事务管理,其实Spring管理事务是通过面向切面编程实现的,所以基础很重要,IoC容器和面向切面编程搞定后,其余都是基于这俩东西的实现,学起来就更加轻松了。要学好Spring不能急,一定要把基础打牢,基础牢固了,这就是磨刀不误砍柴工。

1.Spring是什么?

Spring是一个开发应用框架,什么样的框架呢,有这么几个标签:轻量级非侵入式一站式模块化,其目的是用于简化企业级应用程序开发。

2. Spring的基本思想

Spring的目标是简化Java应用开发,那么它是通过什么方式来实现这一目标的呢?前面我们说过Ioc和AOP是Spring的核心功能,更准确地说,Spring通过为DI和AOP这两种编程技术提供支持,来让应用更方便的进行开发。此外,Spring提倡基于POJO(Plain Old Java Object)的编程模型,提供了针对企业开发且屏蔽重复代码的工具类。在开始正式进入代码编写之前,我们先了解Spring简化开发的几个基本思想。

2.1 Ioc

2.1.1 简介

面向对象的程序通过一组对象之间相互通信来实现特定功能,这里的通信具体来说就是一个对象对另一个对象的方法调用或者属性访问。比如有一个BlogRespositry类负责将博客内容存储到数据库,一个BlogController负责解析前端的Web请求。BlogController接受到新建博客的请求之后,需要调用BlogRespositry的方法来保存博客内容。这里BlogRespositry就是BlogController的一个依赖,具体体现在BlogController会包含一个BlogRespositry类型的成员变量。

  1. class BlogController {
  2. private BlogRepository blogRepository;
  3. public BlogController() {
  4. this.blogRepository = new BlogRepository();
  5. ...
  6. }
  7. ...
  8. }

在上面的代码中,BlogRespositry在构造函数中自己去创建BlogRepository类的实例。而使用依赖注入技术,则BlogRespositry的依赖(即BlogRepository类)是由外部实例化之后注入给它的。依赖注入也称为控制反转(IoC,Inversion of Controll)。当创建一个对象时,它所依赖的对象由外部传递给它,而非自己去创建所依赖的对象(向例子中这样通过new操作)因此,也可以说在对象如何获取它的依赖对象这件事情上,控制权反转了。这便是控制反转和依赖注入这两个名字的由来了。
Spring框架 - 图1

当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了

  1. ![image.png](https://cdn.nlark.com/yuque/0/2019/png/320833/1568275128584-599cc55c-1515-4cea-bf49-02976f9e4df3.png#align=left&display=inline&height=615&name=image.png&originHeight=418&originWidth=340&size=21620&status=done&width=500)

2.1.2 技术实现方式

如何将依赖的对象准备好呢(依赖注入),常用的有两种方式:构造方法注入和setter注入
构造器注入,它就代表了当Person这个对象生成时,就准备好了

  1. public Person(Food food) {
  2. this.food = food;
  3. }

setter注入

  1. public void setFood(Food food) {
  2. this.food = food;
  3. }

2.1.3 基本思路:

将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类(假设这个类名是A),分配的方法就是调用A的setter方法来注入,而不需要你在A里面new这些bean了。

2.1.4 原理

从上面就已经说了:IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。

  • 原理就是通过Java的反射技术来实现的!通过反射我们可以获取类的所有信息(成员变量、类名等等等)!
  • 再通过配置文件(xml)或者注解来描述类与类之间的关系
  • 我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了!

上面描述的技术只要学过点Java的都能说出来,这一下子可能就会被面试官问倒了,我们简单来看看实际Spring IOC容器是怎么实现对象的创建和依赖的:
Spring框架 - 图2

  1. 根据Bean配置信息在容器内部创建Bean定义注册表
  2. 根据注册表加载、实例化bean、建立Bean与Bean之间的依赖关系
  3. 将这些准备就绪的Bean放到Map缓存池中,等待应用程序调用

Spring容器(Bean工厂)可简单分成两种:

  • BeanFactory
    • 这是最基础、面向Spring的
  • ApplicationContext
    • 这是在BeanFactory基础之上,面向使用Spring框架的开发者。提供了一系列的功能!

几乎所有的应用场合都是使用ApplicationContext!

2.2 AOP

面向切面编程(Aspect Oriented Programming,AOP)是一种关注点分离的技术,通俗的说就是有机地将各部分代码进行分离,各司其职,互不干扰。软件开发中经常提一个词,叫做“业务逻辑”或者“业务功能”,我们的代码主要就是实现某种特定的业务逻辑。但是我们往往不能专注于业务逻辑,比如我们写业务逻辑代码的同时,还要关注事务管理、缓存、日志等一系列通用功能,如果每个业务功能都要和这些通用功能混在一起,是一件非常低效和痛苦的事情。所以,为了将业务功能的关注点和通用化功能的关注点分离开来,就需要AOP技术了。通用功能的代码实现,对应的就是我们说的切面(Aspect)。
简而言之,AOP就是一种在开发时将业务相关代码和业务无关的通用功能代码有机分离,而运行时又能够整合到一起形成完整功能的一整套技术。Spring框架中一些模块本身就是基于AOP技术来实现的,例如事务处理和安全相关的模块。

2.3 基于POJO的编程模型

Java开发领域的一大特色就是有大量开源框架可供我们选择和使用。通常情况下,使用一种开发框架,我们编写的业务类都需要去继承框架提供的类或者接口,如此方能使用框架提供的基础功能。而对于Spring框架,只需POJO就能使用其强大的功能。Spring不强制我们依赖于其特定的API,这称之为“非侵入式”开发,能够让代码更加简单并且更容易复用。

2.3.1 JavaBeans

POJO是Plain Old Java Object的缩写,指的是一个普通Java类。也就说,你随便编写一个Java类,就可以称之为POJO。之所以要提出这样一个专门的术语,是为了与基于重量级开发框架的代码相区分,比如EJB,我们编写的类一般都要求符合特定编码规范,实现特定接口、继承特定基类,而POJO则可以说是百无禁忌,灵活方便。
大家在学习过程中会经常遇到另外两个概念:JavaBeans和Spring Bean。这两者和POJO这个概念经常联系在一起,这里简单介绍一下。

  • JavaBeans是一种Java规范定义的一种组件模型,它包含了一些类编码的约定。简单来说
  • 这个类必须有一个公共的缺省构造函数
  • 这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范
  • 这个类应是可序列化的

因为这些要求主要是靠约定而不是靠实现接口,所以许多开发者把JavaBean看作遵从特定命名约定的POJO.当一个Pojo可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,他就是一个JavaBean.

2.3.2 Spring Bean

Spring Bean是被Spring维护和管理的POJO。最早Spring只能管理符合JavaBeans规范的对象,这也是为什么称之为Spring Bean的原因。但是现在只要是POJO就能被Spring容器管理起来,而且这也是最为常见的情况。

3. Spring结构图

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。

Spring框架 - 图3
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。