Spring 基本概念
七大组成
- AOP
- ORM
- Web
- DAO
- Context
- Web MVC
- Core
- Spring Boot
- 快速开发脚手架
- 快速开发单个微服务
- 约定大于配置
- Spring Cloud
- 基于 SpringBoot 实现的
弊端:发展太久,违背原来的理念。配置繁琐,人称 ‘配置地狱’
Spring 和 SpringMVC 的区别:都是容器,spring 用来管理 dao 和 service,springmvc 用来管理 controller
IoC 理论推导 (Inversion of Control)
原来的实现
- UserDao 接口
- UserDaoImpl 实现类
- UserService 业务接口
- UserServiceImpl 业务实现类
用户的需求可能影响到原来的代码,我们需要根据用户需求修改源代码(修改 UserDaoImpl 中的 Dao 生成)
通过 set 方法注入后,实现被动接受对象,需求由外部决定。不在管理对象创建,专注于扩展业务。
1 | // UserServiceImpl 中对 UserDao 的引用 |
IoC 的本质
控制反转是一种设计思想,DI(Dependency Injection) 是 IoC 的一种实现方式,将对象的创建交给第三方,获取对象的方式的反转。
Spring 是一种实现控制反转的 IoC 容器,常见的有两种对象控制方式,XML 和 注解。XML 配置 Bean, 定义和实现是分离的。注解方式则把两者结合在了一起,从而达到零配置。
IoC创建对象的方式
- 默认使用无参构造创建对象
- 通过 constructor-arg 标签实现带参构造器功能
在 xml 加载完后,配置的对象就已经被创建了
Spring 配置说明
- alias 别名,和 bean 的 name 属性重复,而且 name 更灵活
- bean 对象生成配置
- import 合并多个 xml 配置文件
DI - 依赖注入
- 构造器注入
- Set方式注入 - 即依赖注入
- 其他注入
依赖: bean 对象的创建依赖容器
注入: bean 对象的所有属性由容器来注入
P/C命名空间注入
在 xml 中导入约束即可使用
1 | xmlns:p="http://www.springframework.org/schema/p" |
P 可以扩展属性注入,一个 tag 解决,不用嵌套xml了
C 可以扩展构造器
Bean 的 作用域(scope)
- singleton - 默认域
- prototype - 每次取 bean 都会产生新对象
1 | <bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/> |
Bean 的自动装配
- 自动装配是 Spring 满足 bean 依赖的一种方式
- Spring 在上下文中自动寻找,并自动给 bean 装配属性
Spring 三种装配方式:
- xml
- 注解
- 隐式的自动装配 bean
使用注解开发
Spring4 之后,要使用注解需要保证 AOP 包已经导入。XML 也需要添加特殊的约束 <context:annotation-config/>
1 |
|
- bean - @Component
- 属性 - @Value
- 衍生的注解 - @Repository - for dao/@Service - for service/@Controller - for controller 作用都是将对象注入到容器
- 自动装配
- @Autowired 通过类型,名字装配。如果不能自动装配属性,可以通过 @Qualifier(value=”xxx)
- @Nullable,允许为空
- @Resource,通过名字,类型装配
- 作用域 - @Scope
- 小结: XML 更加万能,使用任何场合;注解只能在自己的class 里使用。
推荐做法:XML 用来管理 Bean,注解只用来注入属性
使用 Java 的方式配置 Spring
JavaConfig 是 Spring 一个子项目, Spring4 之后成为核心项目。通过 @Configuration 注解来实现,可以代替 xml。也有像 Import 这样的东西,可以包含其他配置类。
代理模式
Spring 必问题 - SpringAOP 和 SpringMVC
代理模式分类
- 静态代理
- 动态代理
静态代理
角色分析
- 抽象角色:一般是接口或抽象类
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理后做一些操作
- 客户:访问代理对象的人
优点:
- 使真实对象操作更纯粹,不用去关注公共业务
- 公共业务交给代理,业务分工
- 公共业务扩展方便
缺点: 一个真实角色产生一个代理角色,代码量翻倍
动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类使动态生成,不是直接写好的
- 动态代理分两大类:基于接口的动态代理/基于类的动态代理
- 接口 - JDK动态代理
- 类 - cglib
- java字节码 - javasist
两个类: Proxy / InvocationHandler
Proxy: 在 handler 中被调用,产生代理的实例
InvocationHandler: 自定义调用过程,返回执行结果
优点:静态的有点 + 一个动态代理类代理的使一个接口,一般对应一类业务
AOP - 横向扩展功能
配置实现01
目标业务点:pointcut, 需要额外添加的附属动作:adviser(MethodBeforeAdvice/AfterReturningAdvice)
然后添加配置文件
1 | <bean id="userService" class="com.jzheng.service.UserServiceImpl"/> |
配置实现02
也可以用自定义类,使用更简单,但是功能比之前的弱,不能操作 Method 之类的属性
1 | public class DiyPointCut { |
1 | <bean id="diy" class="com.jzheng.diy.DiyPointCut"/> |
注解实现
类添加 Aspect 注解, 在方法上添加注解, 方法注解中可以指定切点。执行顺序:环绕前 -> 方法前 -> 方法 -> 环绕后 -> 方法后
1 |
|
1 | <!-- 方式3, 注解方式 --> |
整合 Mybatis
- 导入包
- junit
- mybatis
- mysql数据库
- spring相关的jar
- aop织入
- mybatis-spring [new]
- 编写配置文件
- 测试
Mybatis
学到第 23 课,跳出去先把 Mybatis 看完再回来。。。。
- 导包
- junit
- mybatis
- mysql
- spring
- aop织入
- mybatis-spring
- 配置文件
- 写测试
mybatis 回忆
- 编写实体类
- 编写核心配置文件
- 编写接口
- 编写 Mapper.xml
- 测试
mybatis-spring
- 编写数据源配置
- sqlSessionFactory
- sqlSessionTemplate
事务回顾
- 要么都成功,要么都失败
- 十分重要,涉及一致性,不能马虎
- 确保完整性和一致性
事务 ACID 原则:
- 原子性
- 一致性
- 隔离性,多个业务可能操作一个资源,防止数据损坏
- 持久性,十五一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中
spring 中的事务管理
- 声明式事务 - AOP
- 编程式事务 - 需要在代码中进行事务管理,侵入性太强,不推荐
为什么需要事务:
- 不添加事务管理,可能存在事务提交不一致
- 如果不在 spring 中配置声明式事务,我们就需要在代码中手动配置事务
- 在项目的开发中十分重要,涉及到数据的一致性