type
status
date
slug
summary
tags
category
icon
password
AI summary
Author:Aaron
Version:9.0.2
一、引言
1.1 原生web开发中存在哪些问题?
传统Web开发存在硬编码所造成的过度程序耦合(例如:Service中作为属性Dao对象)。部分Java EE API较为复杂,使用效率低(例如:JDBC开发步骤)。侵入性强,移植性差(例如:DAO实现的更换,从Connection到SqlSession)。
二、Spring框架
2.1 概念
Spring是一个项目管理框架,同时也是一套Java EE解决方案。Spring是众多优秀设计模式的组合(工厂、单例、代理、适配器、包装器、观察者、模板、策略)。Spring并未替代现有框架产品,而是将众多框架进行有机整合,简化企业级开发,俗称"胶水框架"。
2.2 访问与下载
官方网站:https://spring.io/
三、Spring架构组成
Spring架构由诸多模块组成,可分类为
- 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient。
- 数据访问:事务,DAO支持,JDBC,ORM,封送XML。
- Spring MVC和 Spring WebFlux Web框架。
- 集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
- 语言:Kotlin,Groovy,动态语言。
Spring架构组成
GroupId | ArtifactId | 说明 |
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | spring-instrument | JVM 引导的仪表(监测器)代理 |
org.springframework | spring-instrument-tomcat | Tomcat 的仪表(监测器)代理 |
org.springframework | spring-jdbc | 支持包括数据源设置和 JDBC 访问支持 |
org.springframework | spring-jms | 支持包括发送/接收JMS消息的助手类 |
org.springframework | spring-messaging | 对消息架构和协议的支持 |
org.springframework | spring-orm | 对象/关系映射,包括对 JPA 和 Hibernate 的支持 |
org.springframework | spring-oxm | 对象/XML 映射(Object/XML Mapping,OXM) |
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | ||
org.springframework | spring-webmvc-portlet | 用于 Portlet 环境的MVC实现 |
org.springframework | spring-websocket | WebSocket 和 SockJS 实现,包括对 STOMP 的支持 |
org.springframework |
四、自定义工厂
4.1 配置文件
4.2 工厂类
五、构建Maven项目
5.1 新建项目
使用IDEA打开已创建的文件夹目录
5.2 选择Maven目录
选择Maven项目
5.3 GAV坐标
GAV坐标
六、Spring环境搭建
6.1 pom.xml中引入Spring常用依赖
6.2 创建Spring配置文件
命名无限制,约定俗成命名有:spring-context.xml、applicationContext.xml、beans.xml
七、Spring工厂编码
定义目标Bean类型
spring-context.xml中的< beans >内部配置bean标签
调用Spring工厂API(ApplicationContext接口)
八、依赖与配置文件详解
Spring框架包含多个模块,每个模块各司其职,可结合需求引入相关依赖Jar包实现功能。
8.1 Spring依赖关系
Spring常用功能的Jar包依赖关系
8.2 schema
配置文件中的顶级标签中包含了语义化标签的相关信息
- xmlns:语义化标签所在的命名空间。
- xmlns:xsi:XMLSchema-instance 标签遵循Schema标签标准。
- xsi:schemaLocation:xsd文件位置,用以描述标签语义、属性、取值范围等。
九、IoC(Inversion of Control )控制反转【重点
】
Inverse Of Controll:控制反转反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健
9.1 项目中强耦合问题
9.2 解决方案
此时,如果需要更换其他UserDAO实现类,则UserServiceImpl不用任何改动!则此时的UserServiceImpl组件变得更加稳健!
十、DI(Dependency Injection)依赖注入【重点
】
10.1 概念
在Spring创建对象的同时,为其属性赋值,称之为依赖注入。
10.2 Set注入
创建对象时,Spring工厂会通过Set方法为对象的属性赋值。
10.2.1 定义目标Bean类型
10.2.2 基本类型 + 字符串类型 + 日期类型
10.2.3 容器类型
10.2.4 自建类型
10.3 构造注入【了解】
创建对象时,Spring工厂会通过构造方法为对象的属性赋值。
10.3.1 定义目标Bean类型
10.3.2 注入
10.4 自动注入【了解】
不用在配置中 指定为哪个属性赋值,及赋什么值.由spring自动根据某个 "原则" ,在工厂中查找一个bean,为属性注入属性值
十一、Bean细节
11.1 控·制简单对象的单例、多例模式
配置< bean scope="singleton | prototype" />
- 注意:需要根据场景决定对象的单例、多例模式。
- 可以共用:Service、DAO、SqlSessionFactory(或者是所有的工厂)。
- 不可共用:Connection、SqlSession、ShoppingCart。
11.2 FactoryBean创建复杂对象【了解】
作用:让Spring可以创建复杂对象、或者无法直接通过反射创建的对象。
FactoryBean解决复杂对象创建
11.2.1 实现FactoryBean接口
接口方法描述
- 注意:isSingleton方法的返回值,需根据所创建对象的特点决定返回true/false。
- 例如:Connection 不应该被多个用户共享,返回false。
- 例如:SqlSessionFactory 重量级资源,不该过多创建,返回true。
11.2.2 配置spring-context.xml
配置与获取方式
11.2.3 特例
获取FactoryBean接口的实现类对象,而非getObject()所生产的对象。
十二、Spring工厂特性
12.1 饿汉式创建优势
工厂创建之后,会将Spring配置文件中的所有对象都创建完成(饿汉式)。提高程序运行效率。避免多次IO,减少对象创建时间。(概念接近连接池,一次性创建好,使用时直接获取)
12.2 生命周期方法
自定义初始化方法:添加“init-method”属性,Spring则会在创建对象之后,调用此方法。自定义销毁方法:添加“destroy-method”属性,Spring则会在销毁对象之前,调用此方法。销毁:工厂的close()方法被调用之后,Spring会毁掉所有已创建的单例对象。分类:Singleton对象由Spring容器销毁、Prototype对象由JVM销毁。
12.3 生命周期注解
初始化注解、销毁注解
12.4 生命周期阶段
**单例bean:**singleton
**多例bean:**prototype
十三、代理设计模式
13.1 概念
将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。
功能分离
13.2 静态代理设计模式
通过代理类的对象,为原始类的对象(目标类的对象)添加辅助功能,更容易更换代理实现类、利于维护。
静态代理
- 代理类 = 实现原始类相同接口 + 添加辅助功能 + 调用原始类的业务方法。
- 静态代理的问题
- 代理类数量过多,不利于项目的管理。
- 多个代理类的辅助功能代码冗余,修改时,维护性差。
13.3 动态代理设计模式
动态创建代理类的对象,为原始类的对象添加辅助功能。
13.3.1 JDK动态代理实现(基于接口)
13.3.2 CGlib动态代理实现(基于继承)
十四、面向切面编程【重点
】
14.1 概念
AOP(Aspect Oriented Programming),即面向切面编程,利用一种称为"横切"的技术,剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
14.2 AOP开发术语
连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。切入点(Pointcut):被Spring切入连接点。通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知等。目标对象(Target):代理的目标对象引介(Introduction):一种特殊的增强,可在运行期为类动态添加Field和Method。织入(Weaving):把通知应用到具体的类,进而创建新的代理类的过程。代理(Proxy):被AOP织入通知后,产生的结果类。切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。
14.3 作用
Spring的AOP编程即是通过动态代理类为原始类的方法添加辅助功能。
14.4 环境搭建
引入AOP相关依赖
spring-context.xml引入AOP命名空间
14.5 开发流程
定义原始类
定义通知类(添加额外功能)
定义bean标签
定义切入点(PointCut)形成切面(Aspect)
14.6 AOP小结
通过AOP提供的编码流程,更便利的定制切面,更方便的定制了动态代理。进而彻底解决了辅助功能冗余的问题;业务类中职责单一性得到更好保障;辅助功能也有很好的复用性。
14.7 通知类【可选】
定义通知类,达到通知效果
14.8 通配切入点
根据表达式通配切入点
14.9 JDK和CGLIB选择
spring底层,包含了jdk代理和cglib代理两种动态代理生成机制基本规则是:目标业务类如果有接口则用JDK代理,没有接口则用CGLib代理
14.10 后处理器
spring中定义了很多后处理器;每个bean在创建完成之前 ,都会有一个后处理过程,即再加工,对bean做出相关改变和调整;spring-AOP中,就有一个专门的后处理器,负责通过原始业务组件(Service),再加工得到一个代理组件。
常用后处理器
14.10.1 后处理器定义
14.10.2 配置后处理器
14.10.3 bean生命周期
构造 》 注入属性 满足依赖 》 后处理器前置过程 》 初始化 》后处理器后置过程 》 返回 》 销毁
14.10.4 动态代理源码(了解)
十五、Spring + MyBatis【重点
】
15.1 配置数据源
将数据源配置到项目中
15.1.1 引入jdbc.properties配置文件
15.1.2 整合Spring配置文件和properties配置文件
15.1.3 Druid连接池可选参数
15.1.4 Druid监控中心
15.1.5 测试监控中心
配置tomcat,并访问protocol://ip:port/project/druid/index.html
15.2 整合MyBatis
将 SqlSessionFactory、DAO、Service 配置到项目中
15.2.1 导入依赖
15.2.2 配置SqlSessionFactory
15.2.3 配置MapperScannerConfigurer
管理DAO实现类的创建,并创建DAO对象,存入工厂管理
- 扫描所有DAO接口,去构建DAO实现
- 将DAO实现存入工厂管理
- DAO实现对象在工厂中的id是:“首字母小写的-接口的类名”,
例如:UserDAO==>userDAO , OrderDAO==>orderDAO
15.2.4 配置Service
十六、事务【重点
】
16.1 配置DataSourceTransactionManager
事务管理器,其中持有DataSource,可以控制事务功能(commit,rollback等)。
注意:DataSourceTransactionManager 和 SqlSessionFactoryBean 要注入同一个DataSource的Bean,否则事务控制失败!!!
####16.2 配置事务通知
基于事务管理器,进一步定制,生成一个额外功能:Advice。此Advice可以切入任何需要事务的方法,通过事务管理器为方法控制事务。
16.3 事务属性
16.3.1 隔离级别
16.3.1.1 概念
isolation 隔离级别
名称 | 描述 |
default | (默认值)(采用数据库的默认的设置) (建议) |
read-uncommited | 读未提交 |
read-commited | 读提交 (Oracle数据库默认的隔离级别) |
repeatable-read | 可重复读 (MySQL数据库默认的隔离级别) |
serialized-read | 序列化读 |
隔离级别由低到高为:read-uncommited < read-commited < repeatable-read < serialized-read
16.3.1.2 特性
安全性:级别越高,多事务并发时,越安全。因为共享的数据越来越少,事务间彼此干扰减少。并发性:级别越高,多事务并发时,并发越差。因为共享的数据越来越少,事务间阻塞情况增多。
16.3.1.3 并发问题
事务并发时的安全问题
问题 | 描述 |
脏读 | 一个事务读取到另一个事务还未提交的数据。大于等于 read-commited 可防止 |
不可重复读 | 一个事务内多次读取一行数据的相同内容,其结果不一致。大于等于 repeatable-read 可防止 |
幻影读 | 一个事务内多次读取一张表中的相同内容,其结果不一致。serialized-read 可防止 |
16.3.2 传播行为
propagation传播行为
当涉及到事务嵌套(Service调用Service)时,可以设置:
- SUPPORTS = 不存在外部事务,则不开启新事务;存在外部事务,则合并到外部事务中。(适合查询)
- REQUIRED = 不存在外部事务,则开启新事务;存在外部事务,则合并到外部事务中。 (默认值)(适合增删改)
16.3.3 读写性
readonly 读写性
true:只读,可提高查询效率。(适合查询)false:可读可写。 (默认值)(适合增删改)
16.3.4 事务超时
timeout事务超时时间
当前事务所需操作的数据被其他事务占用,则等待。
- 100:自定义等待时间100(秒)。
- 1:由数据库指定等待时间,默认值。(建议)
16.3.5 事务回滚
rollback-for 回滚属性
如果事务中抛出 RuntimeException,则自动回滚如果事务中抛出 CheckException(非运行时异常 Exception),不会自动回滚,而是默认提交事务处理方案 : 将CheckException转换成RuntimException上抛,或 设置 rollback-for="Exception"
16.4 编织
将事务管理的Advice 切入需要事务的业务方法中
十七、注解开发
17.1 声明bean
用于替换自建类型组件的 <bean...>标签;可以更快速的声明bean
@Service 业务类专用 @Repository dao实现类专用 @Controller web层专用@Component 通用@Scope 用户控制bean的创建模式
17.2 注入(DI)
用于完成bean中属性值的注入
@Autowired 基于类型自动注入@Resource 基于名称自动注入@Qualifier("userDAO") 限定要自动注入的bean的id,一般和@Autowired联用@Value 注入简单类型数据 (jdk8种+String)
17.3 事务控制
用于控制事务切入
- @Transactional
- 工厂配置中的 <tx:advice.... 和 <aop:config... 可以省略 !!
17.4 注解所需配置
17.5 AOP开发
17.5.1 注解使用
17.5.2 配置
十八、集成JUnit
18.1 导入依赖
18.2 编码
可以免去工厂的创建过程;可以直接将要测试的组件注入到测试类。
- 作者:IT小舟
- 链接:https://codegym.top/article/Spring
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。