Spring学习
@(学习)[ Markdown, Spring, MarkDown, Markdown]
Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的java开发框架,有Rod Johnson创建。简单来首,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级
开源框架
Spring叫做EE开发的一站式框架
一站式框架:有EE开发的每一层解决方案
- WEB层:SpringMVC
- Service层:Spring 的Bean管理,Spring声明式事务
- DAO层:Spring的jdbc模板,Spring的ORM模板
Spring的入门
什么是IOC
IOC:Inversion of Control(控制反转)
控制反转:将对象的创建权反转给(交给)Spring
下载Spring的开发包
-
spring-framework-3.0.2.RELEASE-dependencies 依赖库
-
spring-framework-4.2.4.RELEASE-dist 最全的包
- docs:Spring的开发规范和API
- libs:Spring的开发jar和源码
- scheme:Spring的配置文件的约束
- spring-framework-4.2.4.RELEASE-docs 文档
- spring-framework-4.2.4.RELEASE-schema 约束
新建一个web项目
- 引入jar基础包
- Beans(spring-beans-4.2.4.RELEASE.jar)
- Core(spring-core-4.2.4.RELEASE.jar)
- Context(spring-context-support-4.2.4.RELEASE.jar)
- spEL(spring-expression-4.2.4.RELEASE.jar)
- 日志包log4接口(spring-framework-3.0.2.RELEASE-dependencies\org.apache.commons\com.springsource.org.apache.commons.logging\1.1.1\com.springsource.org.apache.commons.logging-1.1.1.jar)
- 日志log4j(spring-framework-3.0.2.RELEASE-dependencies\org.apache.log4j\com.springsource.org.apache.log4j\1.2.15)
- 创建对应的接口和类
- applicationContext的约束
到spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html里寻找bean的约束
<?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">
</beans>
- 配置applicationContext.xml
- 编写测试类
IOC和DI
IOC:控制反转,将对象的创建权反转给了Spring
DI:依赖注入,前提必须有IOC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来
###类之间的关系
- 依赖:比如方法之中的参数传递依赖
- 继承:
- 聚合:has a
#Spring的工厂类
-
BeanFactory:老版本的工厂类
调用getBean的时候,才会生成类的实例 -
ApplicationContext:新版本的工厂类
加载配置文件的时候就会将Spring管理的类都实例化
两个实现类
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
Spring的配置
XML的配置
添加XML Catalog url为
http://www.springframework.org/schema/beans/spring-beans.xsd
还有本地的约束
spring-framework-4.2.4.RELEASE-schema\beans\spring-beans-4.2.xsd
Bean 的相关配置
标签的id和name的配置
- id:使用了约束中的唯一约束,里面不能出现特殊字符的
- name:没有使用约束中的唯一约束,里面可以出现特殊字符
Bean的生命周期的配置(了解)
- init-method:Bean被初始化的时候执行的方法
- destroy-method:Bean被销毁的时候执行的方法(单例close ApplicationContext时关闭)
##Bean的作用范围的配置(重点) - scope :Bean的作用范围
- singleton :默认的,Spring会采用单例模式创建这个对象
- prototype:多例模式
- request: 应用在WEB项目中,Spring创建这个类以后,将这个类存入到request范围中
- session: 效果参考上条
- globalsession:应用在web项目中,必须在porlet环境下使用,如果没有这种环境,相同于session
Spring属性注入
- 构造方法属性注入
- set方法属性注入
- p名称空间注入
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
重点在于添加这句
xmlns:p="http://www.springframework.org/schema/p"
- SpEL的属性注入
集合类型的属性注入
…
#Spring 的分模块开发设置
- 在加载配置文件的时候加载多个
ApplicationContext applicationContext=new ClassPathxmlApplicationContext("applicationContext.xml","applicationContext2.xml")
- 在一个配置文件中引入多个配置文件
<import resource="applicationContext2.xml">
Spring的整合web项目
演示Spring和web项目中一些问题
每次请求都会创建Spring的工厂,浪费服务器资源
解决
- 在服务器启动的时候创建Spring的工厂
- 将工厂保存到ServletContext中
- 每次获取工厂的时候从ServletContext中获取
整合web项目
- 引入Spring_web.jar
- 配置ContextLoaderListener
<!-- 配置Spring的核心监听器>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
在Action中获取工厂
ServletContext sc=ServletAction.getServletContext();
WebApplicationContext applicationContext=WebApplicationContextUtils.getWebAppliactionContext(sc);
- 默认加载的是/WEB-INF/applicationContext.xml
- 配置修改加载配置文件的路径
- 通过工具类获取工厂
#Spring的IOC的注解开发
- 引入Spring的配置文件
在src下创建applicationContext.xml
引入约束:使用注解开发引入context约束 - 使用IOC的注解开发,配置组件扫描
<context:component-scan base-package=“packageName”>
- 在类上添加注解
@Component(“userDao”)
//类似于
注解方式设置属性的值
属性可以没有set方法
在set方法或者属性上添加@Value() 注解就可以
Spring的IOC注解的详解
-
@Component:组件
- 修饰一个雷,将这个类交个Spring管理
- 这个注解有三个衍生注解(功能类似)
- @Controller: web层
- @Service: service层
- @Repository: dao层
-
属性注入的注解
- 普通属性:
- @Value:设置普通属性的值
- 对象类型注入:
- @Autowired: 设置对象类型的属性的值,但是按照类型完成属性注入 ps:往往和Qualifier一起使用,来完成和名称一块使用
- @Resoure:完成对象类型的属性注入,按照名称完成注入// @Resource(name=“customerDao”)
- 普通属性:
-
生命周期相关的注解(了解)
- @PostConstrust :初始化方法
- @PreDestroy : 销毁方法
-
Bean作用范围的注解
- @Scope : 作用范围
IOC的XML和注解开发比较
XML和注解的比较
- 使用场景:
- XML:可以适用任何场景
- 结构清晰,维护方便
- 注解:有些地方用不了,这个类不是自己提供的
- 开发方便
- XML:可以适用任何场景
XML和注解整合开发
- XML管理Bean,注解完成属性注入
<!--在没有扫描的情况下,使用属性注入的注解@Resource,@Value,@Autowired @Qulifier -->
<context:annotation-config/>
Spring的AOP的XML开发
什么是AOP
AOP(面向切面编程)
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
##为什么学习Aop
对程序进行增强
Spring底层的AOP实现原理
- 动态代理
- JDK动态代理:只能对实现了接口的类产生代理
- Cglib动态代理(类似于javassist第三方代理技术:对没有实现接口的类产生代理对象,生成子类对象)
Spring的AOP底层实现(了解)
省略
Spring的AOP的开发(AspectJ的XML的方式)
Spring的AOP的简介
AOP思想最早是由AOP联盟组织提出的,Spring使用这种思想最好的框架
Spring的AOP有自己实现的方式(非常繁琐)。AspectJ是一个AOP的框架,Spring引入Aspect作为自身AOP的开发
####Spring两套AOP开发方式
Spring传统方式(弃用)
Spring基于AspectJ的AOP的开发(使用)
AOP的开发的相关术语
- Joinpoint:连接点,可以被拦截到的点
- 增删改查的方法都可以被增强,这些方法就可以称为是连接点
- PointcutL切入点,真正被拦截到的点
- 在实际开发中,只对save进行方法的增强,save称为是切入点
- Advice:通知,增强。
方法层面的增强
- 现在对save方法进行权限校验,权限校验的方法称为是通知
- Introduction:引介。
类层面的增强
- Target:被增强的对象
- 对UserDao增强,UserDao称为是目标
- Weaving:织入,将通知应用(Adivce)到目标(Target)过程
- 将权限校验的方法代码应用到UserDao的save方法
- Proxy:代理对象
- Aspect: 切面,多个通知和多个切入点组合!
切入点表达式
- 再配置切入点的时候,需要定义表达式,重点的格式如下:execution(public * *(…)),具体展开如下:
-
切入点表达式的格式如下:
- execution([修饰符] 返回值类型 包名.类名.方法名(参数))
-
修饰符可以省略不写,不是必须要出现的。
-
返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
-
包名例如:com.itheima.demo3.BookDaoImpl
- 首先com是不能省略不写的,但是可以使用 * 代替
- 中间的包名可以使用 * 号代替
- 如果想省略中间的包名可以使用 …
-
类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
-
方法也可以使用 * 号代替
-
参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 …
-
Spring中通知类型
-
前置通知
- 在目标类的方法执行之前执行。
- 配置文件信息:<aop:after method=“before” pointcut-ref=“myPointcut3”/>
- 应用:可以对方法的参数来做校验
-
最终通知
- 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
- 在配置文件中编写具体的配置:<aop:after method=“after” pointcut-ref=“myPointcut3”/>
- 应用:例如像释放资源
-
后置通知
- 方法正常执行后的通知。
- 在配置文件中编写具体的配置:<aop:after-returning method=“afterReturning” pointcut-ref=“myPointcut2”/>
- 应用:可以修改方法的返回值
-
异常抛出通知
- 在抛出异常后通知
- 在配置文件中编写具体的配置:<aop:after-throwing method=“afterThorwing” pointcut-ref=“myPointcut3”/>
- 应用:包装异常的信息
-
环绕通知
- 方法的执行前后执行。
- 在配置文件中编写具体的配置:<aop:around method=“around” pointcut-ref=“myPointcut2”/>
- 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。
-
引介通知:
Spring的AOP的入门(AspectJ的XML的方式)
-
步骤一:创建JavaWEB项目,引入具体的开发的jar包
- 先引入Spring框架开发的基本开发包
- 再引入Spring框架的AOP的开发包
-
spring的传统AOP的开发的包
- spring-aop-4.2.4.RELEASE.jar
- com.springsource.org.aopalliance-1.0.0.jar
-
aspectJ的开发包
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- spring-aspects-4.2.4.RELEASE.jar
-
-
步骤二:创建Spring的配置文件,引入具体的AOP的schema约束
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
-
步骤三:创建包结构,编写具体的接口和实现类
- com.ali.spring.aopDemo
- UserDao – 接口
- UserDaoImpl – 实现类
- com.ali.spring.aopDemo
-
步骤四:将目标类配置到Spring中
<!--配置AOP-->
<bean id="userDao" class="com.ali.spring.aopDemo.UserDaoImpl"></bean>
- 步骤五:定义切面类
package com.ali.spring.aopDemo;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspectXml {
// 切面增强的方法
// 前置通知的方法
public void beforeAdvise() {
System.out.println("前置通知");
}
// 后置增强的方法示例
public void afterReturningAdvise(Object result) {
// 后置通知可以获得返回值
System.out.println("后置通知--目标类返回值=" + result);
}
// 环绕通知的方法示例
// 返回值要是Object 参数要是ProceedingJoinPoint类型
public Object aroundAdvise(ProceedingJoinPoint joinPoint) throws Throwable{
// 环绕前置
System.out.println("环绕前置通知");
// 目标对象方法执行,会抛出Throwable异常
Object o = joinPoint.proceed();
// 环绕后置
System.out.println("环绕后置通知");
return o;
}
// 最终通知的方法示例
public void afterAdvise(){
System.out.println("最终通知======");
}
// 异常抛出通知示例
public void afterThrowingAdvise(Throwable e){
System.out.println("异常抛出通知====异常信息:"+e.getMessage());
}
}
- 步骤六:在配置文件中定义切面类
<bean id="myAspectXml" class="com.ali.spring.aopDemo.MyAspectXml"></bean>
7. 步骤七:在配置文件中完成aop的配置
aop:config
<aop:pointcut id=“pc1” expression=“execution(* com.ali.spring.aopDemo..save(…))"/>
<aop:pointcut id=“pc2” expression="execution( com.ali.spring.aopDemo..delete(…))"/>
<aop:pointcut id=“pc3” expression="execution( com.ali.spring.aopDemo..update(…))"/>
<aop:pointcut id=“pc4” expression="execution( com.ali.spring.aopDemo.*.select(…))”/>
<aop:aspect ref=“myAspectXml”>
<aop:before method=“beforeAdvise” pointcut-ref=“pc1”/>
<aop:after-returning method=“afterReturningAdvise” returning=“result” pointcut-ref=“pc2”/>
<aop:around method=“aroundAdvise” pointcut-ref=“pc3”/>
<aop:after method=“afterAdvise” pointcut-ref=“pc4”/>
<aop:after-throwing method=“afterThrowingAdvise” pointcut-ref=“pc4” throwing=“e”/>
</aop:aspect>
</aop:config>
8. 完成测试
package com.ali.spring.aopDemo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
//固定给事
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class aopDemoTest {
// 注入Bean
@Resource(name = “userDao”)
private UserDao userdao;
@Test
public void testBefore(){
userdao.save();
}
@Test
public void testAfterReturning(){
userdao.delete();
}
@Test
public void testAround(){
userdao.update();
}
@Test
public void testAfter(){
userdao.select();
}
@Test
public void testAfterThrowing(){
userdao.select();
}
}
# Spring的注解方式
1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包
* 先引入Spring框架开发的基本开发包
* 再引入Spring框架的AOP的开发包
* spring的传统AOP的开发的包
* spring-aop-4.2.4.RELEASE.jar
* com.springsource.org.aopalliance-1.0.0.jar
* aspectJ的开发包
* com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
* spring-aspects-4.2.4.RELEASE.jar
2. 步骤二:创建Spring的配置文件,引入具体的AOP的schema约束
<?xml version="1.0" encoding="UTF-8"?>
3.步骤三:在配置文件中开启aop的注解模式
<aop:aspectj-autoproxy />
4. 步骤四:创建包结构,编写具体的接口和实现类
* com.ali.spring.aopAnnoDemo
* OrderDao -- 接口
* OrderDaoImpl -- 实现类
5. 步骤五:将目标类配置到Spring中
<!--配置AOP-->
<bean id="OrderDao" class="com.ali.spring.aopAnnoDemo.OrderDaoImpl"></bean>
6. 步骤六:定义切面类
```java
package com.ali.spring.aopAnnoDemo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
//切面类需要添加@Aspect注解
@Aspect
public class MyAspect {
// 前置增强演示
@Before(value = "execution(* com.ali.spring.aopAnnoDemo.*.save(..))")
public void log() {
System.out.println("-----来自MyAspect类的增强------");
}
// 后置增强演示,注解的不同参数之间使用,隔开。returning接受道德是返回值
@AfterReturning(value = "execution(* com.ali.spring.aopAnnoDemo.*.delete(..))", returning = "result")
public void afterReturning(Object result) {
System.out.println("------后置增强----参数----" + result);
}
// 环绕增强演示
@Around(value = "execution(* com.ali.spring.aopAnnoDemo.*.update(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 环绕前增强
System.out.println("环绕-前通知");
// 执行目标方法,会抛出运行时异常Throwable
Object obj = joinPoint.proceed();
// 环绕后增强
System.out.println("环绕-后通知--被增强方法体的返回值--===" + obj);
// 环绕增强中,注意要求有返回值,否则会抛异常
return obj;
}
// 异常抛出通知
@AfterThrowing(value = "pc4()" ,throwing = "e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出通知---"+e);
}
// 最终通知
@After(value = "pc4()" )
public void after(){
System.out.println("----------来自最终通知-----");
}
//注解AOP切入点的配置
@Pointcut(value = "execution(* com.ali.spring.aopAnnoDemo.*.find(..))" )
public void pc4() {}
}
- 编写测试类测试
SpringJDBC模板的使用
SpringJDBC模板的介绍
Spring是EE开发的一站式的框架,有EE开发的每层的解决方案。Spring对持久层也提供了解决方案:ORM块和JDBC的模板。
Spring提供了很多的模板用于简化开发:
Spring Jdbc模板入门
相同的部分
- 导包
- 四个基本包
- 两个日志包
- aop的包
- spring-aop-4.2.4.RELEASE.jar
- mysql的jdbc驱动包
- mysql-connector-java-5.1.46.jar
- Spring JDBC模板支持包
- spring-jdbc-4.2.4.RELEASE.jar
- Spring JDBC模板事务支持包
- spring-tx-4.2.4.RELEASE.jar
- 配置applicationContext.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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
- 创建数据库
create database spring4_day03;
use spring4_day03;
create table account(
id int primary key auto_increment,
name varchar(20),
money double
);
基础版
@Test
public void save(){
// 数据库连接池
DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
// dataSource.setUrl("jdbc:mysql///spring4_day03");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring4_day03");
dataSource.setUsername("root");
dataSource.setPassword("123");
JdbcTemplate jdbcTemplate=new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
jdbcTemplate.update("insert into account values (null,?,?)","张三",627d);
}
进阶版-结合Spring对数据库连接池进行管理
配置文件
<!--JDBCTemplate项目示例-->
<!--配置dataSource 数据库原-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--设置数据库连接驱动-->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring4_day03"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
java文件
@Test
public void save2(){
// 数据库连接池
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate =(JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.update("insert into account values (null,?,?)","李四",628d);
}
使用DBCP版
导入dbcp包
xml文件
<!--JDBCTemplate项目示例-->
<!--配置dbcp数据库原-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!--设置数据库连接驱动-->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring4_day03"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!--配置JDBCTemplate模板-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
java文件
// dbcp版
@Test
public void save3(){
// 数据库连接池
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate =(JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.update("insert into account values (null,?,?)","王五",629d);
}
使用c3p0版
导入c3p0包
c3p0的配置和dbcp的配置一样。不过是bean的参数变了。具体如下
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--设置数据库连接驱动-->
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring4_day03"/>
<property name="user" value="root"/>
<property name="password" value="123"/>
</bean>
增删改查
增删改都是通过jdbcTemplate.update()方法来执行。只是执行语句不同(示例。update方法后面的参数是可变参数,个数随?个数变化)
this.getJdbcTemplate().update("update account set money=money-? where name=?" ,money,to);
###查方式
@Test
public void find(){
// 获取IOC容器
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取jdbcTemplate
JdbcTemplate jdbcTemplate=(JdbcTemplate)applicationContext.getBean("jdbcTemplate");
=获取查询到的单个属性=
String name =jdbcTemplate.queryForObject("select name from account where id =1",String.class);
//获取查到的对象
Account account =jdbcTemplate.queryForObject("select * from account where id=1", new RowMapper<Account>() {
@Override
public Account mapRow(ResultSet resultSet, int i) throws SQLException {
Account account=new Account();
account.setId(resultSet.getInt("id"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getDouble("money"));
return account;
}
});
System.out.println(account);
}
获取集合和获得对象的方法一样,只是需要使用query()方法
//省略
抽取配置到属性文件
- 定义一个属性文件
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring4_day03
jdbc.userName=root
jdbc.password=123
2.在Spring的配置文件中引入属性文件
* 第一种:
<!--导入jdbc配置文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
* 第二种
<context:property-placeholder location="classpath:jdbc.properties"/>
- 在bean中引用配置文件的属性
<!--配置c3p0数据库原-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--设置数据库连接驱动-->
<!--通过${属性}来引用-->
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.userName}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
Spring事务管理
##事务回顾
###什么事务
事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败。
1.4.1.2 事务的特性
原子性:事务不可分割
一致性:事务执行前后数据完整性保持一致
隔离性:一个事务的执行不应该受到其他事务的干扰
持久性:一旦事务结束,数据就持久化到数据库
###如果不考虑隔离性引发安全性问题
读问题
脏读 :一个事务读到另一个事务未提交的数据
不可重复读 :一个事务读到另一个事务已经提交的update的数据,导致一个事务中多次查询结果不一致
虚读、幻读 :一个事务读到另一个事务已经提交的insert的数据,导致一个事务中多次查询结果不一致。
写问题
丢失更新
解决读问题
设置事务的隔离级别
Read uncommitted :未提交读,任何读问题解决不了。
Read committed :已提交读,解决脏读,但是不可重复读和虚读有可能发生。
Repeatable read :重复读,解决脏读和不可重复读,但是虚读有可能发生。
Serializable :解决所有读问题。
Spring的事务管理API
PlatformTransactionManager:平台事务管理器
- 平台事务管理器:接口,是Spring用于管理事务的真正的对象。
- DataSourceTransactionManager :底层使用JDBC管理事务
- HibernateTransactionManager :底层使用Hibernate管理事务
TransactionDefinition :事务定义信息
- 事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读
TransactionStatus:事务的状态
- 事务状态:用于记录在事务管理过程中,事务的状态的对象。
事务管理的API的关系:
- Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。
#Spring的事务的传播行为
##Spring中提供了七种事务的传播行为:
-
保证多个操作在同一个事务中
- PROPAGATION_REQUIRED :默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
- PROPAGATION_SUPPORTS :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
- PROPAGATION_MANDATORY :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
-
保证多个操作不在同一个事务中
- PROPAGATION_REQUIRES_NEW :如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
- PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理。
- PROPAGATION_NEVER :如果A中有事务,报异常。
-
嵌套式事务
- PROPAGATION_NESTED :嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。
Spring的事务
##搭建Spring的事务管理的环境
Spring的事务管理:一类:编程式事务(需要手动编写代码)–了解
-
第一步:配置平台事务管理器
-
第二步:Spring提供了事务管理的模板类
配置事务的管理的模板类
-
第三步:在业务层注入事务管理的模板
-
编写事务管理的代码
-
测试:
1.4.6 Spring的事务管理:二类:声明式事务管理(通过配置实现)—AOP
XML方式的声明式事务管理
- 第一步:引入aop的开发包
- 第二步:恢复转账环境
- 第三步:配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 第四步: 配置增强
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--事务管理的规则-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
- 第五步:AOP的配置
<aop:config>
<aop:pointcut id="pc1" expression="execution(* com.ali.spring.transactionManageDemo.serviceImpl.AccountServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc1"/>
</aop:config>
6.测试
注解方式的声明式事务管理
- 第一步:引入aop的开发包
- 第二步:恢复转账环境
- 第三步:配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 第四步:开启注解事务
<!--开启注解事务-->
<tx:annotation-driven transaction-manager="transactionManager" />
- 在业务层添加注解
@Transactional
//可以传参数,具体省略
6.测试
#整合SSH开发

@ContextConfiguration(“classpath:applicationContext.xml”)
记得导入正确的包
接着需要使用哪些属性注入就可以了