Spring学习笔记
Spring
基本概念
四个核心依赖:
spring-core:核心 jar 包spring-beans:对象创建 jar 包spring-context:上下文容器 jar 包(包含了其它 3 个依赖)spring-expression:表达式 jar 包
IOC
1. 基本概念
IOC:控制反转。
创建对象的权利,或者是控制的位置,由 Java 代码转移到 spring 容器,由 spring 的容器控制对象的创建,就是控制反转。
「对象的创建交给容器」
spring 创建对象时,会读取配置文件中的信息,然后使用反射给我们创建好对象之后在容器中存储起来,当我们需要某个对象时,通过 id 获取对象即可,不需要我们自己去 new。
2. 配置文件
- 文件位置:
resources - 文件名:
xxx.xml
配置 bean 对象:<bean id="..." class="..."></bean>
3. 获取对象
- 创建一个容器(IOC)对象并解析 xml 配置文件。
- 实例化配置文件中的 bean 对象(反射)并发放入容器。
- 获得类的字节码:
Class clazz = Class.forName("com.msb.dao.impl.EmpDaoImpl") - 通过字节码实例化对象:
Object obj = clazz.newInstance() - 将对象放到一个 Map 中:
map.put("empDao",obj)
- 获得类的字节码:
- 通过 bean id 从容器中获取对象。
- 工厂模式返回 bean 对象:
getBean(beanId)
- 工厂模式返回 bean 对象:
4. IOC 接口
实际开发一般使用:
- 接口:
ApplicationContext - 实现类:
ClassPathXmlApplicationContext
5. 应用示例

6. 依赖注入
DI:依赖注入(bean 对象属性的赋值)
对象的属性包括:基本数据类型、其它类、引用类型。DI 处理的是对象的属性赋值和互相依赖的关系。
7. Bean 对象
(1) 属性设置
scope:
singleton:单例prototype:每一次获取会创建新的实例(相当于new)request:请求域session:会话域application:应用域
lazy-init:
- 懒加载:调用
getBean()时再实例化对象
(2) 生命周期
- 通过构造器创建 bean 实例(构造方法)
- 默认使用无参的构造方法
- 为 bean 属性赋值(
set方法)- 基本数据类型赋值
- 引用类型注入
- 后置处理器:
BeanPostProcesser - 初始化 bean(
init方法)- 需要在 bean 标签中配置
init-method="方法名"
- 需要在 bean 标签中配置
- 后置处理器:
BeanPostProcesser - bean 的获取(
getBean方法) - 关闭容器并销毁 bean 工厂(
destroy方法)- 容器关闭:
context.close() - 需要在 bean 标签中配置
destroy-method="方法名"
- 容器关闭:
定义后置处理器:
1 | public class MyBeanProcesser implements BeanPostProcessor { |
配置后置处理器:
<bean id="myBeanProcesser" class="com.msb.beanProcesser.MyBeanProcesser"></bean>
(3) 自动装配
Autowire:
byName:根据目标 id 值(bean id)和属性值注入byType:根据类型(bean class)注入
(4) 常用注解
对象创建:
@Component:放在类上,用于标记,告诉 spring 当前类需要由容器进行实例化并放入容器中(所有对象均可以使用该注解)。@Controller:控制层@Service:业务层@Repository:持久层
依赖注入:
@Autowired:根据属性数据类型自动装配- 不需要依赖
set方法 - 属性类型可以是接口,会自动匹配对应的实现类对象
- 同一个类型,在 bean 中只能有一个对象,否则会报错
- 不需要依赖
@Qualifier:根据属性名称注入依赖- 当一个接口有多个实现类,可以使用
@Qualifier指定要使用的实现类名称 - 在实际开发中一般不会使用
@Qualifier,因为一般在 DAO 层,一个接口只会有一个实现类
- 当一个接口有多个实现类,可以使用
@Resources:根据类型或名称注入- 不配置 name,根据类型注入
- 配置 name,根据名称注入,如:
@Resource(name="userDaoImplB")
@Value:注入普通数据类型
AOP
1. 基本概念
AOP:面向切面编程
- 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性和开发的效率。
- 可以在不修改现有代码的情况下,对程序的功能进行拓展,往往用于日志处理、权限控制、性能检测、事务控制等。
原理:动态代理。
常用术语:
- Joint point(连接点):可以被增强的方法
- Pointcut(切入点):实际被增强的方法
- Advice(通知):实际增强的逻辑部分
- Target(目标对象):被代理的对象
- Aspect(切面):功能相关的一些 Advice 方法放在一起声明成的一个 Java 类
- Weaving(织入):创建代理对象并实现功能增强(将 Aspect 和其它对象连接起来,并创建 Adviced object 的过程)
2. 代理模式
(1) 静态代理
- 代理类与被代理类都需要实现同一个接口
- 一个静态代理类只能代理一个类
静态代理需要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。然而在实际开发中我们是可能是有非常多的类是需要被代理的,并且事先我们可能并不知道我们要代理哪个类。所以如果使用静态代理会增加许多的工作量,并且效率低下,代码复用率也不好。
(2) 动态代理
- 可以对不特定的类、方法进行代理
- 可以在程序运行时动态的变化代理的规则
- 代理类在程序运行时才创建
分类:
Proxy:JDK 动态代理(面向接口)Cglib:第三方依赖(面向父类)
使用示例:
1 | // 通过 Porxy 动态代理类获得一个代理对象,在代理对象中,对某个方法进行增强 |
总结:在不修改原有代码,或者没有办法修改原有代码的情况下,增强对象功能。使用代理对象,代替原来的对象去完成功能,进而达到拓展功能的目的。
3. 配置文件
依赖文件:
spring-aspects:切面包aspectjweaver:织入包aopalliance:AOP 联盟包
自动生成代理对象:
<aop:aspectj-autoproxy/>
4. 切点表达式
execution([权限修饰符] [返回值类型] [类的全路径名] [方法名](参数列表))
*表示所有的权限修饰符- 返回值类型可以省略不写
- 参数列表
(..)表示不做限制
5. 切面
1 | // 实例化该类,初始化bean |
执行流程:
- 环绕通知(
@Around) - 前置通知(
@Before) - 切点方法
- 返回通知(
@AfterReturning) - 后置通知(
@After) - 环绕通知(
@Around)
声明式事务
1. 基本概念
事务的管理应该放在 service 层进行处理。
声明式事务的底层实现就是 AOP(动态代理)。
2. 配置文件
1 | <!--配置事务管理器--> |
3. 注解
@Transactional:
自动实现事务控制,方法前自动开启事务,若出现异常,则自动回滚后提交;若方法正常执行完成,则自动提交事务。
- 加在类上:对类中的所有方法都添加了事务控制
- 加在方法上:仅对当前方法添加了事务控制
参数设置:
1 |
(1) 传播行为
当在一个事务中又包含了几个更小的事务,多事务方法之间发生调用时,事务是如何管理的?
propagation:
PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。(默认)PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
(2) 隔离级别
isolation:……
SpringMVC
执行流程
核心:前端控制器
三大组件:处理器映射器、处理器适配器、视图解析器。

- 前端控制器:MVC 模式中的 C,是整个流程控制的中心,由它调用其它组件处理用户的请求。
- 处理器映射器:根据用户请求(URL)找到对应的处理器(Handler,即 Controller 中的处理单元)。
- 处理器适配器:对处理器进行执行。
- 视图解析器:将处理结果生成 View 视图,然后对 View 进行渲染并通过页面展示给用户。
常用注解
@RequestMapping:用于建立请求 URL 和处理请求方法之间的对应关系。
@RequestParam:把请求中指定名称的参数给 Controller 中方法的形参赋值。
1 |
|
@PathVariable:用于绑定 URL 中的占位符。
1 |
|
@ResponseBody:让 Controller 方法返回 json 数据。
单元方法的返回值不按照请求转发或者重定向处理,而是按照直接响应处理,将单元方法的返回值直接响应给浏览器。
@RestController:@Controller + @ResponseBody
返回 json 数据不需要在方法前面加 @ResponseBody 注解了,但使用 @RestController 这个注解,就不能返回 jsp、html 页面,视图解析器无法解析 jsp、html 页面。