Spring简介
- 概念
- 优势
问题引入
编译器依赖&运行时依赖
工厂模式解耦
1 | 通过上面的JDBC驱动案例,下面我们来改造平时我们的案例。把`编译器依赖`改为`运行时依赖` |
IOC概念
Inversion Of Control
控制反转
原本我们要new创建对象的活,现在不需要我们创建了。创建对象的控制权交给了工厂。
IOC入门
改造工厂模式解耦
使用Spring来改造上面的工厂模式解耦
示例
上面的BeanFactory.java
和bean.properties
就可以删除了。
- 引入依赖
1
2
3
4
5
6
7<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies> - 在resources目录下创建
bean.xml
文件1
2
3
4
5
6
7
8
9
10
11<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--把对象的创建交给spring来管理-->
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
</beans> - 测试
1
2
3
4
5
6
7
8
9
10public static void main(String[] args) {
//1.获取核心容器对象【加载类路径下的bean.xml】
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取Bean对象【两种方式都可】
IAccountDao accountDao = ac.getBean("accountDao", IAccountDao.class);
IAccountService accountService = (IAccountService)ac.getBean("accountService");
System.out.println(accountDao);// com.itheima.dao.impl.AccountDaoImpl@29774679
System.out.println(accountService);// com.itheima.service.impl.AccountServiceImpl@3ffc5af1
}
ApplicationContext三个常用的实现类
ApplicationContext与BeanFactory创建对象的时机
Bean的三种创建方式
这里是XML的三种创建方式。
还可以使用@Controller @Service @Repository指定类来创建 或 @Bean指定方法返回值创建
Bean的作用范围
Bean的生命周期
依赖注入(DI)
简介
1 | 依赖注入:【它是spring框架核心ioc的具体实现。】 |
三种方式
- 构造函数注入
- set方法注入
简单类型
复杂类型
- 注解注入,参考@Autowired @Qualifier @Resource @Value
XML方式改造JDBC
JdbcTemplate的CRUD
注解
配置
需要先配置bean.xml文件,才能使用注解
1 |
|
创建对象的
【相当于:<bean id="" class="">
】
1 | @Component: |
注入数据的
【相当于:<property name="" ref="">
<property name="" value="">
】
1 | Autowired: |
- Autowired的查找原理
- Qualifier作用于变量或方法参数。Resource的用法
改变作用范围的
【相当于:<bean id="" class="" scope="">
】
1 | Scope(不指定,默认单例) |
生命周期相关的
【相当于:<bean id="" class="" init-method="" destroy-method="" />
】
1 | PreDestroy |
其他注解
【用法可以参考下面的纯注解改造JDBC
】
1 | Configuration |
改造Junit
1 | 使用Junit单元测试:测试我们的配置 |
纯注解改造JDBC
动态代理实现事务控制
动态代理可参考Java动态代理实现的两种方式
- 错误分析(多个连接,多个事务)
- 代码实现
AOP
全称是Aspect Oriented Programming
即:面向切面编程。
应用场景
场景一: 记录日志
场景二: 监控方法运行时间 (监控性能)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
相关术语
1 | + Joinpoint(连接点)【被invoke执行的方法】 |
要明确的事
1 | 我们要做的: |
XML方式使用
1 | 1、通知类配置成Bean,交给spring来管理 |
1 | 切入点表达式的写法: |
- 简单实现
前置增强
打印日志案例 - 提取
切入点
,演示环绕增强
注解方式使用
- 注解AOP,演示
前置增强
与环绕增强
同时使用。 - 改造纯注解实现AOP
- 注解AOP:注意:注解AOP的最终增强会在后置增强或异常增强前执行。
AOP控制事务
XML实现
注解实现
- 动态代理实现事务控制【注解方式的AOP的
最终
会在异常
或后置
前面执行,所以要使用环绕增强
实现。】
事务控制
1 | 声明式事务也是基于AOP来实现的。 |
XML方式
- spring中基于XML的声明式事务控制配置步骤关于事务可参考事务
1
2
3
4
5
6
7
8
9
10
111、配置事务管理器
2、配置事务的通知
此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的
使用tx:advice标签配置事务通知
属性:
id:给事务通知起一个唯一标识
transaction-manager:给事务通知提供一个事务管理器引用
3、配置AOP中的通用切入点表达式
4、建立事务通知和切入点表达式的对应关系
5、配置事务的属性
是在事务的通知tx:advice标签的内部
注解方式
- spring中基于注解 的声明式事务控制配置步骤
1
2
31、配置事务管理器
2、开启spring对注解事务的支持
3、在需要事务支持的地方使用@Transactional注解
编程式(了解)
【为什么不用这种?就是因为每个Dao处理,都需要把逻辑写在重写的那个execute方法中】
Spring5
- Spring5的JDK版本>=1.8,Tomcat版本>=8.5【JDK1.8反射创建对象要比1.7快】
- @NonNull 注解和@Nullable 注解的使用
用 @Nullable(可空) 和 @NotNull(不可空) 注解来显示表明可为空的参数和以及返回值。
这样就够在编译的时候处理空值而不是在运行时抛出 NullPointerExceptions。