IOC
概念
控制反转,把对象创建和对象之间的调用过程交给spring管理
目的
降低耦合
IOC容器
IOC容器底层就是对象工厂
实现两种方式:(两个接口)
BeanFactory
IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
ApplicationContext
BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用加载配置文件时候就会把在配置文件对象进行创建
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
IOC操作Bean管理(xml方式)
创建对象
<bean id="唯一标识" class="包类路径"></bean>
注入方式
set方法
<bean id="User" class="包类路径">
<property name="类里面属性的名称" value="向属性注入的值"></property>
</bean>
有参构造函数注入
<bean id="User" class="包类路径">
<constructor-arg name="类里面属性的名称" value="向属性注入的值"></constructor-arg>
</bean>
注入其他属性
字面量
<!--null 值-->
<property name="address">
<null/>
</property>
<!--属性值包含特殊符号
1 把<>进行转义 < >
2 把带特殊符号内容写到 CDATA
<property name="address">
<value><![CDATA[<<南京>>]]></value>
</property>
外部Bean
<property name="唯一标识" ref="其他Bean的唯一标识"></property>
内部Bean
<property name="对象属性">
<bean id="唯一标识" class="包类路径">
<property name="对象中的属性" value="值"></property>
</bean>
</property>
数组
<property name="courses">
<array>
<value>java 课程</value>
<value>数据库课程</value>
</array>
</property>
List
<property name="courses">
<list>
<value>java 课程</value>
<value>数据库课程</value>
</list>
</property>
Map
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
Set
<property name="courses">
<set>
<value>java 课程</value>
<value>数据库课程</value>
</set>
</property>
集合里面设置对象类型
<property name="courses">
<list>
<ref bean=""></ref>
<ref bean=""></ref>
</list>
</property>
bean作用域
在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
默认值是单实例对象 singleton
多实例对象 prototype
bean生命周期
1)通过构造器创建 bean 实例(无参数构造)
2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
3)把 bean 实例传递 bean 后置处理器的方法postProcessBeforeInitialization
4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
5)把bean实例传递bean后置处理器的方法postProcessAfterInitialization
6)bean 可以使用了(对象获取到了)
7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
自动装配
<!--实现自动装配
bean 标签属性 autowire,配置自动装配
autowire 属性常用两个值:
byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
byType 根据属性类型注入
-->
引入外部属性文件到spring配置中
//第一步 引入外部属性文件
<context:property-placeholder location="classpath:jdbc.properties"/>
//第二步 使用
<property name="类里面属性的名称" value="${外部属性文件的key值}"></property>
IOC操作Bean管理(注解方式)
Spring注解
@Component |
---|
@Service |
@Controller |
@Repository |
注解实现对象创建
1)引入依赖
2)开启组件扫描
//在不使用默认 filter
<context:component-scan base-package="包目录"
use-default-filters="false">
//设置扫描哪些内容
<context:include-filter type="annotation"
expression="类包路径"/>
</context:component-scan>
3)使用注解
注解实现属性注入
注解 | 解释 |
---|---|
@Autowired | 根据属性类型进行自动装配 |
@Qualifier | 根据名称进行注入(需配合@Autowired使用) |
@Resource | 可以根据类型注入,可以根据名称注入 |
@Resource 根据类型进行注入 | |
@Resource(name=“”) 根据名称进行注入 | |
@Value | 注入普通类型属性 |
AOP
概念
面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
不通过修改源代码方式,在主干功能里面添加新功能
AOP底层原理(动态代理)
JDK动态代理
(动态代理有接口)创建接口实现类代理对象,增强类的方法
使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
CGLIB动态代理
(动态代理没有接口)创建子类的代理对象,增强类的方法
AOP术语
连接点 | 类里面那些方法可以被增强,这些方法称为连接点 | |
---|---|---|
切入点 | 实际被真正增强的方法,成为切入点 | |
通知(增强) | 实际增强的逻辑部分称为通知(增强) | |
前置通知 | ||
后置通知 | ||
环绕通知 | ||
异常通知 | ||
最终通知 | ||
切面 | 是动作 |
切入点表达式
作用
知道对哪个类里面的哪个方法进行增强
语法结构
语法结构: execution([权限修饰符] [返回类型] [类全路径] 方法名称 )
AOP注解
注解 | 解释 |
---|---|
@Aspect | 生成代理对象 |
@Pointcut | 相同切入点抽取 |
@Before | 前置通知 |
@AfterReturning | 后置通知(返回通知) |
@After | 最终通知 |
@AfterThrowing | 异常通知 |
@Around | 环绕通知 |
@Order | 设置增强类优先级 |
Spring事务
概念
事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操
作都失败
特性
1)原子性
2)一致性
3)隔离性
4)持久性
Spring进行事务管理
编程式事务管理
声明式事务管理(使用)
底层使用AOP原理
基于xml配置文件方式
配置事务管理器
<!--1、创建事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2、配置通知-->
<tx:advice id="txadvice">
<!--配置事务参数-->
<tx:attributes>
<!--指定哪种规则的方法上面添加事务-->
<tx:method name="accountMoney" propagation="REQUIRED"/>
<!--<tx:method name="account*"/>-->
</tx:attributes>
</tx:advice>
<!--3、配置切入点和切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pt" expression="execution(*
com.atguigu.spring5.service.UserService.*(..))"/>
<!--配置切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>
基于注解方式(使用)
开启事务注解
//配置类中使用注解开启事务
@EnableTransactionManagement
添加事务注解
1)@Transactional,这个注解添加到类上面,也可以添加方法上面
2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
3)如果把这个注解添加方法上面,为这个方法添加事务
@Transactional参数配置
propagation(事务传播行为)
传播属性 | 描述 |
---|---|
REQUIRED | 支持当前事务,如果当前有事务, 那么加入事务, 如果当前没有事务则新建一个(默认情况) |
NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务就把当前事务挂起,执行完后恢复事务(忽略当前事务) |
SUPPORTS | 如果当前有事务则加入,如果没有则不用事务 |
MANDATORY | 支持当前事务,如果当前没有事务,则抛出异常(当前必须有事务) |
NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常(当前必须不能有事务) |
REQUIRES_NEW | 支持当前事务,如果当前有事务,则挂起当前事务,然后新创建一个事务,如果当前没有事务,则自己创建一个事务 |
NESTED | 如果当前存在事务,则嵌套在当前事务中。如果当前没有事务,则新建一个事务自己执行(和required一样)。嵌套的事务使用保存点作为回滚点,当内部事务回滚时不会影响外部事物的提交;但是外部回滚会把内部事务一起回滚回去。(这个和新建一个事务的区别) |
ioslation(事务隔离级别)
事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
读问题 | 描述 |
---|---|
脏读 | 一个未提交事务读取到另一个未提交事务的数据 |
不可重复读 | 一个未提交事务读取到另一提交事务修改数据 |
虚读 | 一个未提交事务读取到另一提交事务添加数据 |
解决:通过设置事务隔离级别,解决读问题
操作说明 | 说明 |
---|---|
@Transactional(isolation = Isolation.DEFAULT) | 默认隔离级别,和数据库的中的4种对应,数据库中用啥,spring事务隔离就用啥 |
@Transactional(isolation = Isolation.READ_UNCOMMITTED) | 读取未提交数据(会出现脏读, 不可重复读,幻读),基本不使用 |
@Transactional(isolation = Isolation.READ_COMMITTED)(SQLSERVER默认) | 读取已提交数据(会出现不可重复读和幻读) |
@Transactional(isolation = Isolation.REPEATABLE_READ) | 可重复读(会出现幻读) |
@Transactional(isolation = Isolation.SERIALIZABLE) | 串行化 |
timeout(超时时间)
1)事务需要在一定时间内进行提交,如果不提交进行回滚
2)默认值是 -1 ,设置时间以秒单位进行计算
readOnly(是否只读)
1)读:查询操作,写:添加修改删除操作
2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作
3)设置 readOnly 值是 true,设置成 true 之后,只能查询
rollbackFor(回滚)
1)设置出现哪些异常进行事务回滚
noRollbackFor(不回滚)
1)设置出现哪些异常不进行事务回滚