Day6 | Java框架 | Spring
- 系统架构
- [Spring 配置:核心容器](#Spring 配置:核心容器)
- [Spring 简化开发:注解开发](#Spring 简化开发:注解开发)
- Spring整合MyBatis
- AOP
- Spring事务
系统架构
Spring 配置:核心容器
核心概念(IoC 和 DI)
Inversion of Control,控制反转:使用对象时,在程序中不要主动使用new产生对象,转换由外部提供对象。此过程中对象创建控制权转移到外部。
- Spring技术对IoC思想进行了实现:IoC容器,用来充当IoC思想中的"外部"。由IoC容器提供对象。
IoC容器
负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
。
Dependency Injection,依赖注入:在容器中建立bean
与bean
之间的依赖关系的过程。
目标:充分解耦
- 使用IoC容器管理bean(IoC)
- 在IoC容器内将有依赖关系的bean进行关系绑定(DI)
最终效果:
- 使用对象时不仅可以直接从IoC容器中获取,并且获取到的Bean已经绑定了所有的依赖关系。
bean
bean配置
基础配置、别名配置、作用范围(默认为单例,控制创建bean实例的数量)
- 适合交给容器进行管理的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
- 不适合交给容器进行管理的bean
- 封装实体的域对象
bean实例化
三种方式。
- 构造方法 (常用):bean本质上就是对象,创建bean使用无参构造方法 。无参构造方法如果不存在,将抛出异常
BeanCreationException
。默认就是构造方法,因此可以省略不写。 - 静态工厂(了解)
- 实例工厂 (了解):由于不是静态方法,需要用对象调取,所以要先new一个工厂对象。
- FactoryBean(实用):代替原始实例工厂中创建对象的方法。实现Factory接口(三个方法:得到bean实例,得到bean类型,控制是否单例)。
bean生命周期
- 初始化容器
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set操作)
- 执行
bean初始化方法
- 使用bean
- 执行业务操作
- 关闭/销毁容器
- 执行
bean销毁方法
- 执行
bean声明周期控制
- 配置
- init-method
- destroy-method
- 接口(了解)
- InitializingBean
- DisposableBean
关闭容器:ConfigurAbleapplicationContext
- close()
- registerShutdownHook()
DI
- 向一个类中传递数据的方式有几种?
- 普通方法(set方法)
- 构造方法
- 依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
- 引用类型
- 简单类型(基本数据类型与String)
依赖注入方式
setter注入
- 简单类型
- 在bean中定义引用类型属性并提供可访问的
set方法
- 配置中使用
property标签value属性
注入引用类型对象
- 在bean中定义引用类型属性并提供可访问的
- 引用类型:
- 在bean中定义引用类型属性并提供可访问的
set方法
- 配置中使用
property标签ref属性
注入引用类型对象
- 在bean中定义引用类型属性并提供可访问的
构造器注入
(了解即可)
- 简单类型
- 在bean中定义引用类型属性并提供可访问的
构造方法
- 配置中使用
constructor-arg标签value属性
注入引用类型对象
- 在bean中定义引用类型属性并提供可访问的
- 引用类型
- 在bean中定义引用类型属性并提供可访问的
构造方法
- 配置中使用
constructor-arg标签ref属性
注入引用类型对象
- 在bean中定义引用类型属性并提供可访问的
对于参数适配问题,有以下两种方式
- 配置中使用
constructor-arg标签type属性
设置按形参类型注入- 配置中使用
constructor-arg标签index属性
设置按形参位置注入
依赖注入方式选择
- 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
- 可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
- 自己开发的模块推荐使用setter注入
依赖自动装配
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程。
自动装配方式
配置中使用bean标签autowire属性
设置自动装配的类型。
- 按类型(常用)
- 按名称
- 按构造方法
- 不启动自动装配
自动装配特征
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配式(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
集合注入
java
数组 int[] array;
List<String> list;
Set<String> set;
Map<String, String> map;
Properties properties;
第三方资源配置管理
数据源对象管理
- 导入druid坐标:
pom.xml
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
- 配置数据源对象作为Spring管理的bean:
applocationContext.xml
xml
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/spring_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
加载properties文件
避免把username等属性直接在xml中填写,而是通过properties文件进行管理:applicationContext.xml
- 开启context命名空间
xml
<?xml version="1.0" encoding="UTF-8?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
- 使用context命名空间,加载指定properties文件
xml
<context:property-placeholder location="jdbc.properties"/>
- 使用${}读取加载的属性值
xml
<property name="username" value="${jdbc.username}"/>
不加载系统属性
xml<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
加载多个properties文件
xml<context:property-placeholder location="jdbc.properties, msg.properties" />
加载所有properties文件
xml<context:property-placeholder location="*.properties" />
加载properties文件标准格式
xml<context:property-placeholder location="classpath:*.properties" />
从类路径或jar包中搜索并加载properties文件
xml<context:property-placeholder location="classpath*:*.properties" />
容器
创建容器
即,容器初始化。有两种加载方式
- 类路径加载配置文件(常用)
java
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- 文件路径加载配置文件
java
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
以上两种加载方式都可以同时加载多个配置文件,中间用逗号,
隔开即可。意思是将多个bean的配置合并到一起。
获取bean
有三种方式:
- 使用bean名称获取:常用
java
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
- 使用bean名称获取,并指定类型
java
BookDao bookDao = ctx.getBean("bookDao", BoolDao.class);
- 使用bean类型获取:要求容器中该类型的bean只有一个
java
BookDao bookDao = ctx.getBean(BookDao.class);
BeanFactory初始化
- 类路径加载配置文件
javaResource resources = new ClassPathResource("applicationContext.xml"); BeanFactory bf = new XmlBeanFactory(resources); BookDao boolDao = bf.getBean("boolDao", BookDao.class); bookDao.save();
- BeanFactory创建完毕后,所有的bean均为延迟加载
小结
容器相关
- BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
- ApplicationContext接口是Spring容器的核心接口,初始化bean时立即加载
- ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
- ApplicationContext接口常用初始化类
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
bean相关
依赖注入相关
Spring 简化开发:注解开发
注解开发bean的定义
原始定义bean
纯注解开发
Spring3.0升级,使用Java类代替配置文件(一点配置文件都不需要写了),开启Spring快速开发
注解开发bean管理
bean作用范围
bean生命周期
在这里插入图片描述
注解开发依赖注入
自动装配
引用类型注入
当有相同类型的bean时,按名称注入
简单类型注入
加载properties文件
注解开发管理第三方bean
第三方bean管理:@bean
手写新的方法,添加@bean,方法的返回值就是一个bean
数组格式为@import({JdbcConfig.class})
扫描式的隐藏性太强,建议使用@import导入式。
第三方bean依赖注入
简单类型:成员变量
引用类型:方法形参
自动装配。按类型注入。
小结
XML配置与注解配置比较
Spring整合MyBatis
思路分析
MyBatis程序核心对象分析
最核心的对象是:SqlSessionFactory
整合MyBatis
MyBatis管的是SqlSessionFactory
对象
Spring整合MyBatis
只有两个Bean要配置
SqlSessionFactoryBean
MapperScannerConfigurer
Spring整合JUnit
- 指定类运行器
- 指定Spring上下文配置
AOP
AOP简介
核心概念:Aspect Oriented Programming,面向切面编程。一种编程范式,指导开发者如何组织程序结构。
作用 :在不惊动原始设计的基础上为其进行功能增强(代理模式也能做增强)。即,原始代码不需要修改。
Spring理念:无侵入式。(代码中无Spring的痕迹,但是Spring对其进行了功能增强)
描述 | AOP核心概念 |
---|---|
原始方法(所有方法) | "连接点" Joinpoint |
要追加功能的方法(共性功能匹配的方法) | "切入点" Pointcut |
共性功能/方法(抽取出来) | "通知" Advice,其依赖的类称为"通知类" |
在哪些切入点上执行哪些通知,描述通知与切入点的对应关系 | "切面" Aspect |
AOP入门案例
AOP工作流程
AOP工作流程
AOP核心概念
- 目标对象(Target):原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的。
- 代理(Proxy):目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现。
SpringAOP本质:代理模式
AOP切入点表达式
- 切入点:要进行增强的方法
- 切入点表达式:要进行增强的方法的描述方式
语法格式
切入点表达式标准格式(不重要)
通配符(重要)
书写技巧
学习过程中慢慢体会,不需要死记硬背
AOP通知类型
5 种类型指的就是 5 种位置。
AOP通知获取数据
一般有三种:获取参数、获取返回值、获取异常(了解)
AOP总结
对接口进行描述,可以降低代码的耦合度。
Spring事务
Spring事务简介
- 事务作用:在数据层保障一系列的数据库操作同成功同失败。
- Spring事务作用:在数据层或业务层 保障一系列的数据库操作同成功同失败。
案例:银行账户转账
- 在业务层接口上添加Spring事务管理
注意事项:- Spring注解式事务通常添加在业务层接口 中而不会添加到业务层实现类中,降低耦合。
- 注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务。
- 设置事务管理器
注意事项:- 事务管理器要根据实现技术进行选择
- MyBatis框架使用的是JDBC事务
- 开启注解式事务驱动
Spring事务角色
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法。
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法。
Spring事务属性
事务配置
案例:转账业务追加日志
事务传播行为
事务传播行为 :事务协调员对事务管理员所携带事务的处理态度: