Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架,它贯穿了表现层、业务层和持久层。
教学视频来自SiKi学院——SSM框架第二季-spring入门
Spring的优点
- 方便解耦,简化开发
- AOP编程的支持
- 声明式事务的支持
- 方便程序的测试
- 方便集成各种优秀的框架
- 降低Java EE API的使用难度
可以根据名字获取对象,也可以根据类型获取对象
Spring IoC|DI 概念介绍(要实现IoC依赖于DI的支持)
IoC(Inversion of Control): 反转控制。将我们自己创建对象的工作交给Spring容器帮我们完成;
DI(Dependcy Injection): 依赖注入。将值通过配置的方式为变量初始化/赋值(注入);
- 注入方式
- set方法注入
- 构造注入
- 属性注入
- 注入类型
- 值类型——八大基本数据类型
- 引用类型——String、自定义对象等
这个依赖关系原来要自己维护,现在让spring来管理
Spring配置
- Xml配置
- Bean元素:交由Spring管理的对象都要配置在bean标签中;
-
Bean标签介绍和创建方式: 空参构造、静态工厂、动态工厂;
空参构造: 配置的bean会在容器被创建的时候使用其空参构造创建出来 设置lazy-init可以使其不自动加载 -
scope标签:
-
scope="singleton"在这里插入图片描述
-
scope=“prototype”
-
scope=“request"or"session”
在web环境下,如果scope属性为request,那么这个对象被创建出来它的生命周期会与request请求一致;session同理,生命周期与session一致.
scope的属性在一般项目中采用singleton,特殊环境下使用prototype
-
-
初始化方法 init-method和销毁方法destroy-method:
容器创建之后立马调用init方法,销毁之前调用destroy方法。
需要注意的是如果是多例,则对象创建后将交由自己处理,spring不再管理,因此不会调用destroy方法
- 属性注入
-
Set方法注入
使用set方法注入则属性必须要具有set方法
值类型注入:
引用类型注入:
-
构造函数注入
指定了参数类型就会根据类型来选择调用哪一个构造函数
指定参数位置则根据位置决定调用哪个构造函数
-
复杂类注入: Array,List,Set,Map,Properties
需要注意的是property的输出中age在前 name在后 -
Spring注解配置
- 导包和约束:aop包+context约束
- 将对象注册到容器内
<!-- applicationContext_annotation.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-4.3.xsd">
<!-- 注解开发 -->
<!-- 开启组件扫描 base-package 扫描该包下以及子包的所有注解 -->
<context:component-scan base-package="com.catherine.bean"></context:component-scan>
</beans>
//User类
import org.springframework.stereotype.Component;
//<bean name="user" class="com.catherine.bean.User"> 相当于@Component("user")
@Component("user")
public class User2 {
private Integer u_id;
private String u_username;
private String u_password;
private Pet u_pet;
....
Component是早期雏形,在现在的项目中为了区别对象属于哪个层,又用了三个与Component功能相似的组件
- @Controller() //对应web层
- @Service() //对应service层
- @Repository() //对应dao层
- 用注解配置Scope属性
@Scope(scopeName=“prototype”)
//不设置则默认为单例
- 注解配置init-method与destroy-method
//在构造方法后调用
@PostConstruct()
public void userInit(){
System.out.println("user init");
}
//在销毁前调用
@PreDestroy()
public void userDestroy()
{
System.out.println("user destroy");
}
- 注解配置属性注入,值类型与引用类型
- 注入值类型
@Value(value=" “)
private String u_username;
//或者
@Value(value=” ")
public void setU_id(Integer u_id){this.u_id=u_id;}
//可以在声明值的上方注入,也可以在set方法上方注入。更加推荐在set方法上方注入,因为在声明值的上方注入是使用暴力反射注入的,破坏了其封装性
- 注入引用类型
- 利用自动装配
@AutoWired
- 利用自动装配
//宠物类
@Component("猫")
public class Pet {
private String petType;
private String color;
public String getPetType() {
return petType;
}
@Value(value="加菲猫")
public void setPetType(String petType) {
this.petType = petType;
}
public String getColor() {
return color;
}
@Value(value="咖啡色")
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Pet [petType=" + petType + ", color=" + color + "]";
}
//User类
@Autowired
public void setU_pet(Pet u_pet) {
this.u_pet = u_pet;
}
但是容器中若有多个Pet类型的对象,使用自动装配就会出现不知道该装配哪一个的问题。
- 手动指定
@Resource(name="猫")
public void setU_pet(Pet u_pet) {
this.u_pet = u_pet;
}
一般使用手动指定,若是容器中只有一个对象那么就可以使用自动装配
- Spring&JUnit进行测试
- 导包:test包
- 使用@RunWith注解创建Spring容器
- 使用@ContextConfiguration读取Spring配置文件
@RunWith(SpringJUnit4ClassRunner.class)//使用junit进行测试,帮我们创建容器。
@ContextConfiguration("classpath:applicationContext_Injection.xml")//读取配置文件
public class Test_JUnit {
@Resource(name="dog")
private Pet p;
@Test
public void Test(){
System.out.println(p);
}
}
- 主配置文件的分包配置
在主配置文件中导入其他配置文件,方便管理
<import resource="/applicationContext_Injection.xml"/>
测试项目源码——ssm_spring
测试项目源码——将spring运用在servlet项目上
Spring-aop
- aop思想(面向切面编程):将纵向重复代码横向抽取解决,简称横切
- Spring中的aop:无需我们自己写动态代理的代码,Spring可以将容器中管理对象生成动态代理对象,前提是我们进行一些设置;
- Spring是基于动态代理的——优先选用Proxy代理
- Proxy动态代理:被代理的对象必须要实现接口;
- Cglib动态代理:被代理的对象不能被final修饰,基于继承;
- Spring aop相关名词说明
- JoinPoint:连接点。 目标对象中,哪些方法会被拦截;
- Pointcut:切入点。筛选连接点,最终要增强的方法;
- Advice:通知/增强。要执行的增强代码;
- Introduction:介入/引入。在执行时期动态加入一些方法或行为;
- Aspect:切面。通知+切入点,通知应用到哪个切入点;
- target:目标。被代理对象;
- weaving:织入。把切面的代码应用到目标对象来创建新的代理对象的过程;
- proxy:代理。把切面的代码应用到目标对象来创建新的代理对象。
- Spring aop配置
- 导包
- spring-aspects和spring-aop
- aop联盟包 -aopaliance
- aop织入包 -aspectj.weaver
- 自定义通知,五种自定义通知类型
- before前置通知
- after最终通知(后置通知)
- afterReturning成功通知(后置通知)
- afterThrowing异常通知(后置通知)
- around环绕通知
Spring与JDBC
- 使用JdbcTemplate操作数据库
导包:新增jdbc、tx - JdbcTemplate的增删改查操作
- 让SPringle容器管理JdbcTemplate
- 继承JdbcDaoSupport甩开JdbcTemplate
- 在Spring中读取配置文件
Spring中的aop事务
- 事务相关知识
- 什么是事务:把多条数据操作捆绑到一起执行,要么都成功,要么都失败
- 事务的原则ACID:
- 原子性:事务包含的所有操作,要么全部成功,要么全部失败回滚,成功的全部应用到数据库,失败不能对数据库有任何影响;
- 一致性:事务在执行前和执行后必须一致。例如A和B一共有100块钱,无论A、B之间如何转帐,他们的钱相加始终都是100‘
- 隔离性:多用户并发访问同一张表时,数据库为每一个用户开启新的事务,该事务不能被其他事务所影响,相互有隔离;
- 持久性:一个事务一旦提交,则对数据库中数据的改变是永久的,即便系统故障也不会丢失
- 并发可能引起的问题:
- 脏读:一个事务读取到另一个事务未提交的数据;
- 不可重复读:一个事务读取到另一个事务已经提交(Update操作)的数据,导致前后读取不一致
- 幻读(虚读):一个事务中读取到别的事务插入(Insert操作)的数据,导致前后读取不一致;
- 事物的隔离级别:根据实际情况选择
- Serializable串行化:可避免脏读、不可重复读和幻读;
- Repeatable read可重复读:可避免脏读、不可重读;(MySQL默认值)
- Read committed读已提交:可避免脏读;
- Read uncommitted读未提交:任何情况都无法保证
- aop事务-搭建环境
- 事务基本操作:打开事务,提交事务,回滚事务;
- Spring中利用接口来管理不同框架的事务操作;
- 通过实现PlatformTransactionManager接口支持不同的框架完成各自的事务处理
- 为不同平台提供对应的事务管理器的实现:JDBC&Mybatis:DataSourceTransactionManager等等
- Spring-aop事务通过配置事务的隔离级别、事务传播行为、是否只读来操作;
- 隔离级别:串行化、可重复读、读已提交、读未提交;
- 是否只读:
- true:不可改变数据库中的数据,查询操作推荐;
- false:可以改变数据库数据
- 事务传播行为:事务方法嵌套调用的规则:xService();->yService();
- REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置时最常用的设置;
- REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务;
- SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行;
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起(暂停);
- MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常;
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常;
- NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则执行与REQUIRED类似的操作。
- xml配置版aop事务
- 使用经典的转账案例进行测试,准备数据:bean、service、dao
- 使用事务需要导入tx包和约束
- 配置事务核心管理器:DataSourceTransactionManager
- 配置事务通知
- 配置aop
测试项目源码——ssm_spring_transaction
Spring整合Mybatis加入事务操作数据库
- 整合Mybatis
- 导包
- Spring:基本包、aop、aspects、jdbc、tx、test
- Mybatis:mybatis-3.4.6
- 整合包:mybatis-spring-1.3.2
- 三方包:aopalliance、aspectj.weaver、c3p0-0.9.5.2、mchange-commons-java-0.2.11、mysql-connector-java-5.1.46-bin、ojdbc7
- 创建项目结构(packge):bean、service、mapper、test
- 创建配置文件:sqlMapperConfig、applicationContext
- 导包
- 创建测试用例:使用Mapper扫描开发,转账
- 再service中加入事务:利用Spring-aop事务解决转账异常问题
- 测试项目源码——spring与mybatis整合