Spring框架是Java平台的一个开源的全栈(Full-stack)应用程序框架和控制反转容器实现,一般被直接称为 Spring。该框架的一些核心功能理论上可用于任何 Java 应用,但 Spring 还为基于Java企业版平台构建的 Web 应用提供了大量的拓展支持。Spring 没有直接实现任何的编程模型,但它已经在 Java 社区中广为流行,基本上完全代替了企业级JavaBeans(EJB)模型。
狭义Spring spring框架
广义Spring Spring生态体系 SpringBoot Springcloud 等
### **Spring 的理解**
是一个容器框架
**非侵入式**框架,框架不会影响或者改变我们原有的编码过程
是一个**轻量级**框架,可以自由选择Spring框架的全部或一部分
是一个**一站式**框架,提供了各种各样的模块,支持开发
提供了对于**持久层**的支持
提供了Web MVC框架
**IOC/DI**,控制反转/依赖注入
**AOP,面向切面编程**
### 历史
第一版由 Rod Johnson 开发,并在2002年10月发布在 *Expert One-on-One J2EE Design and Development* 一书中。2003年6月,Spring Framework 第一次发布在 Apache 2.0 许可证下。2004年3月,发布了里程碑的版本1.0,2004年9月以及2005年3月,又发布了新的里程碑版本。2006年,Spring Framework 获得了 Jolt 生产力奖 和 JAX 创新奖。
2006年10月发布Spring 2.0,2007年11月 Spring 2.5,2009年12月 Spring 3.0,2011年 Spring 3.1,2013年11月 Spring 3.2.5,2013年12月发布了4.0版本。值得注意的是,Spring 4.0 版本中增加了对 Java SE 8, Groovy 2, Java EE 7 的一些方面以及 WebSocket 的支持。
2017年9月 Spring Framework 正式发布了 5.0 版本,此版本引入了 Spring WebFlux,一个高性能、响应式、异步的 Web 框架。Spring 5.0 重点加强了对函数式编程、响应式程序设计(reactive programming)的支持能力,是一个非常大的进步。
### Spring框架
![1618317009080](assets/1618317009080.png)
#### 1. Data Access/Integration(数据访问/集成)
数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。
- JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
- ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、[Hibernate](http://c.biancheng.net/hibernate/) 和 iBatis 提供了的集成层。
- OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
- JMS 模块:指 [Java](http://c.biancheng.net/java/) 消息服务,包含的功能为生产和消费的信息。
- Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。
#### 2. Web 模块
Spring 的 Web 层包括 Web、
Servlet、Struts 和 Portlet 组件,具体介绍如下。
- Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
- Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
- Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
- Portlet 模块:提供了在 Portlet 环境中使用 MVC实现,类似 Web-Servlet 模块的功能。
#### 3. Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。
- Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
- Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
- Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
- Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。
#### 4. 其他模块
Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。
- AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
- Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
- Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
- Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。
### 核心功能模块
强大的基于 JavaBeans 的采用控制反转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加简易快捷。一个可用于 Java EE 等运行环境的核心 Bean工厂。数据库事务的一般化抽象层,允许声明式(Declarative)事务管理器,简化事务的划分使之与底层无关。内建的针对 JTA 和单个 JDBC 数据源的一般化策略,使Spring的事务支持不要求 Java EE 环境,这与一般的 JTA 或者 EJB CMT 相反。
JDBC 抽象层提供了有针对性的异常等级(不再从 SQL 异常中提取原始代码),简化了错误处理,大大减少了程序员的编码量。再次利用 JDBC 时,你无需再写出另一个'终止'(finally)模块。并且面向 JDBC 的异常与 Spring 通用数据访问对象(Data Access Object)异常等级相一致。
以资源容器,DAO 实现和事务策略等形式与 Hibernate,JDO 和 MyBatis 、SQL Maps 集成。利用控制反转机制全面解决了许多典型的 Hibernate 集成问题。所有这些全部遵从 Spring 通用事务处理和通用数据访问对象异常等级规范。
灵活的基于核心 Spring 功能的 MVC 网页应用程序框架。开发者通过策略接口将拥有对该框架的高度控制,因而该框架将适应于多种呈现(View)技术,例如 JSP、FreeMarker、Velocity、Thymeleaf 等。值得注意的是,Spring 中间层可以轻易地结合于任何基于 MVC 框架的网页层,例如 Struts、WebWork 或 Tapestry。提供诸如事务管理等服务的AOP框架。在设计应用程序 Model 时,MVC模式(例如 Struts)通常难于给出一个简洁明了的框架结构。Spring 却具有能够让这部分工作变得简单的能力。程序开发员们可以使用Spring的JDBC抽象层重新设计那些复杂的框架结构。
## Spring框架核心
**核心就是管理资源组件及其依赖关系。包括IoC(Inversion
of Control 控制反转)/ DI (Dependency Injection依赖注入),Aop(Aspect
Oriented Programming面向切面编程)**
### 初始化 Bean
Spring 加载容器时,初始化 Bean
配置选项:lazy-init
默认 default:false(初始化 Bean)
如果为 true 时,调用 getBean 时再初始化
4. Bean 生命周期
***注意 - 以下条件,必须实现 BeanFactory 接口***
- 初始化
1. if Bean 实现了接口 BeanBameAware.setBeanName 则调用
2. if Bean 实现了接口 BeanFactoryAware.setBeanFactory 则调用
3. if Bean 实现了接口 BeanPostProcessor.postProcessBeforeInitializaion 则调用
4. if Bean 实现了接口 BeanFactoryPostProcessor.afferPropertiesSet 则调用
5. if Bean 实现了自定义初始化方法,则调用
6. if Bean 实现了接口 BeanPostProcessor.postProcessAfterInitialization 则调用
以上步骤均完成,则初始化完毕
- 销毁
1. if Bean 实现了接口 DisposableBean.destory 则调用
2. if Bean 实现了自定义初始化方法,则调用
#### IOC
**IOC解决了类与类之间的紧耦合**
IoC(Inversion of Control 控制反转):资源(组件)不再由使用资源双方进行管理,而是由不使用资源的第三方统一管理,这样带来的好处。第一,资源的集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度
IOC **控制反转**
不是一种技术,而是一个面向对象编程的法则 , 控制反转是从容器的角度来说的,以前对象都是应用程序new出来的,对象之间的依赖也是应用程序自己创建的,从而导致类与类之间高耦合,难于测试。现在,**由Spring管理bean的生命周期以及bean之间的关系,降低了业务对象替换的复杂性,提高了组件之间的解耦**。对资源进行集中管理,实现了资源的可配置和易管理;隐藏细节,不用自己组装,我们只负责调用。
Spring的IOC是面向接口编程,帮助我们生产bean,管理bean,管理bean与bean之间的依赖关系,通过读取Spring的配置文件代码从上往下进行加载,读取bean标签中配置的class地址,调用它的无参构造方法,创建出对象同时可以使用set方法赋值,构造方法赋值,注解赋值,在bean与bean之间的关系进行注入时,可以通过ref将一个实例化的bean注入到另一个bean的属性之中。
Spring的IOC默认是单例模式,在单例模式里面每次返回的都是同一个对象,如果你想调用时再创建,我们可以在beans标签中的设置default-lazy-init = “true” 设置为延时加载,如果你想每次返回的实例都是一个新的实例,需要设置他为prototype类型,正常情况下创建的实例是不会销毁的,是一直存在的(关闭tomcat自动销毁)。
#### DI
DI **依赖注入**
是从应用程序的角度来说的,即,应用程序依赖Spring管理的bean以及bean之间的关系。Spring容器中有很多bean的实例,它会将符合依赖关系的对象通过注入的方式进行关联,建立bean与bean之间的联系
**实现 Ioc 容器**的两个方式(已有实例,用于赋值)
1. **依赖查找**
2. **依赖注入**
Spring 主要采用 " 依赖注入 ",而 " 依赖注入 " 则有三种方式:
1. **构造器**
2. **setter**
3. **接口**
其中 “ 构造器 ”、“ setter ” 方法最常用,**而 “ 接口 ” 用于从其他地方注入**
#### AOP
Aop(Aspect Oriented
Programming面向切面编程):我们知道OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分,如果在应用开发过程中,如果产生横切性问题,比如日志记录,权限验证,监控性能等,这个时候AOP就上场了,AOP是通过预编译方式或者运行期动态代理实现的一种方式,AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
**AOP,面向切面编程**
利用一种称为“横切”的技术,支持将公共业务提取出来(例如:安全/事务/日志)进行集中管理,面向核心业务编程,只需要关注业务本身,而不用去关注公共业务。使用AOP可以将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性
Spring的AOP是aop是面向切面,相当于使用代理管理被代理对象的方法,在方法执行前后加上各种通知,用于展示方法什么时候开始,或者出错了要回滚,一般用来管理业务层。实现有两种方式:
一种直接使用spring的**cglib**动态代理:cglib动态代理和jdk代理机制不一样,被代理类不需要实现接口,直接可以用代理类管理被代理对象,代理类需要实现MethodInterceptor接口,代理类创建代理时要创建一个Enhancer用与生成代理对象,把被代理对象设置成代理对象的父类,并且代理对象为回调对象。
一种是静态织入,先创建一个普通的类,当作切面类,然后在xml文件中加入此类,然后配置各种通知的标签。
也可以通过给被代理类打上注解告诉代理这个类被代理了。。
SpringMVC运行原理and执行流程:
项目在启动通过加载配置在web.xml中的SpringMVC核心控制器DispatcherServlet,DispatcherServlet通过注入springmvc的配置文件给contextConfigLocation属性赋值读取配置文件的信息;利用Spring之一特性IOC通过<context:component-scan base-package="需要扫描的包"></context:component-scan>对指定的包进行扫描,加载带有@Controller注解的类纳入到容器中进行管理(实例化bean);客户端发送url请求通过web.xml中配置的url进行拦截匹配,匹配到满足需求的路径会进入到DispatcherServlet核心控制器,核心控制器通过查找handl