Spring快速上手笔记!!!

1.Spring(一个轻量级的控制反转IOC和面向切面变成AOP的框架)

1.1优点

  • 免费开源的框架
  • 轻量级的非入侵式的框架
  • IOC,AOP
  • 支持事务的处理,对框架整合的支持

1.2拓展

  • spring boot
    • 一个快速开发的脚手架
    • 基于它可以快速的开发单个微服务
    • 约定大于配置
  • spring cloud
    • 它是基于spring boot实现的3

1.3核心概念

  • IOC控制反转:代码耦合度偏高的话,使用对象时再程序中不主动使用new产生对象,转换为由外部提供对象。(即对象的创建控制权由程序转移到外部,这种思想叫做控制反转)(目标:充分 解耦)

    • spring提供容器成为IOC容器,提供对象。(将对象放进ioc容器里,管理对象创建和初始化过程)

    • IOC容器负责对象的创建初始化等一系列工作,这个对象在IOC中统称为==Bean==

  • DI依赖注入

    • 在IOC中建立bean和bean之间的依赖关系的整个过程叫做DI依赖注入

2.IOC

2.1入门案例

  • 导入Spring坐标
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-content</artifactId>
    <version>5.2.10</version>
</dependency>
  • 定义Spring管理的类(接口)
  • 创建spring’‘配置文件,配置对应类作为Spring管理的bean
<bean id="bookservice" class="com.itheima.service.impl.BookServiceImpl"></bean>

id不能重复

  • 初始化IOC容器,通过容器获取bean
//加载配置文件得到上下文对象,也就是容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取资源bean
BookService bookService = (BookService) ctx.getBean("bookService")
bookService.save();

3.DI

3.1入门案例

  • 基于IOC管理bean
  • Service中使用的new形式创建的对象不在保留
  • 为service中的对象进入到service中提供方法
  • 用配置描述service与对象之间的关系
//配置service与dao对象的关系
<bean id="bookservice" class="com.itheima.service.impl.BookServiceImpl">
	//property表示当前bean的属性
    //name属性表示配置哪一个具体的属性
    //ref属性表示参照哪一个bean
    <property name="bookDao" ref="bookDao"/>    
</bean>

4. Bean

4.1别名配置:

  • 定义bean的别名,可以定义多个,使用逗号,分号,空格分隔。

4.2 bean作用范围

<bean id="bookservice" name="Dao" class="com.itheima.service.impl.BookServiceImpl" scope="prototype"> //默认scope="singleton"单例(是同一个对象)   prototype是多例(不是同一个对象)
  • 适合交给容器进行管理的bean:变现层对象,业务层对象,数据层对象,工具对象
  • 不适合交给容器的bean:封装实体的域对象

4.3 bean实例化

  • bean本质上就是对象,创建bean使用构造方法完成
4.3.1 构造方法
  • 提供可访问的构造方法
public class BookDaoImpl implements BookDao{
    public BookDaoImpl(){
		System.out.println("123");
    }
    public void save(){
        System.out.println("321");
    }
}
  • 配置
<bean
    id="bookDao"
    class="com.itheima.dao.impl.BookDaoImpl"
    />
  • 无参构造方法如果不存在,将抛出异常BeanCreationException
4.3.2 使用静态工厂实例化bean
  • 静态工厂
public class OrderDaoFactory{
    public static OrderDao getOrderDao(){
        return new OrderDaoImpl();
    }
}
  • 配置
<bean
    id="orderDao"
    factory-method="getOrderDao"
    class="com.itheima,factory.OrderDaoFactory"
    />
4.3.3 使用实例工厂实例化bean
  • 配置
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>//先把实例造出来。配合使用,没有实际意义

<bean id="UserDao" factory-method="getUserDao" factory-bean="UserFactory"/>
//factory-bean指向工厂实例,factory-method方法名不固定每次需要配置!!可以优化
4.3.4 使用factoryBean实例化(属于实例工厂的一种)
public class UserDaoFactoryBean implements FactoryBean<UserDao>{
    public UserDao getObject() throws Exception{
		return new UserDaoImpl;
    }
    public class<?> getObjectType(){
        return UserDao.class;
    }
    //isSingleton()函数是设置单例或者非单例的,就是对象地址是不是一样的
    public boolean isSingleton(){
        return true;
    }
}
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>

4.4Bean生命周期

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到销毁的整个过程
  • bean生命周期控制:在bean创建后到销毁前做的一些事情
<bean id="bookDao" class="com.itheima.factory.BookServiceImpl" init-method="init" destory-method="destory"/>
4.4.1生命周期控制:在关虚拟机之前先关闭容器(利用钩子)
public class BookDaoImpl implements BookDao {
    public void save(){
		System.out.println("book dao save ...");
    }
	public void init(){
		System.out.println("book init ...");
    }
	public void destory(){
		System.out.println("book destory ...");
    }
}
//加载配置文件得到上下文对象,也就是容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取资源bean
BookService bookService = (BookService) ctx.getBean("bookService")
bookService.save();
ctx.registerShutdownHook();//关闭钩子(任何时候都可以)
4.4.2使用接口控制生命周期

实现InitializingBean,DisposableBean接口

public class BookServiceImpl implements BookService , InitializingBean, DisposableBean {
    public void save(){
        System.out.println("book service save ...");
    }
	public void afterPropertiesSet() throws Exception{
        System.out.println("afterPropertiesset");
    }
	public void destroy() throws Exception {
        System.out.println("destroy");
    }
}

5.依赖注入

传递数据的方式:

  • 普通方法(set方法):提供一个set方法,用ref引用bean
  • 构造方法

依赖注入的数据分为两种类型:

  • 引用类型
  • 简单类型(基本数据类型和String)

依赖注入方式:

  • setter注入
    • 简单类型
    • 引用类型
  • 构造方法注入
    • 简单类型
    • 引用类型

两种依赖方式的选择:

  • 强制依赖使用构造器注入,使用setter注入有概率不进行注入导致null对象出现
  • 可选依赖使用setter注入,灵活性强
  • Spring框架倡导使用构造器,第三方框架内部大多数使用构造器注入的形式进行数据初始化,相对严谨
  • 实际开发中,如果受控对象没有提供setter方法就必须使用构造器注入
  • 自己开发的模块推荐使用setter注入

5.1 setter注入

需要构建一个set构造方法

public class BookDaoImpl implements BookDao{
    private String databaseName;
    public setdatabaseName(String databaseName){
        this.databaseName=databaseName
    }
    public void save(){
        System.out.println("123");
    }
}

value参数

//setter注入
<bean id="bookDao" class="com.itheima.service.impl.BookDaoImpl">
	//property表示当前bean的属性
    //name属性表示配置哪一个具体的属性
    //value属性表示注入的值
    <property name="databaseName" value="mysql"/>   //数据类型 
    <property name="bookDao" ref="bookDao"/>  //引用类型
</bean>

5.2构造方法注入

  • 在bean中引用类型属性并提供可访问的构造方法
public class BookserviceImpl impletments BookService{
    private BookDao bookDao;
    public BookServiceImpl(BookDao bookDao){
        this.bookDao=bookDao;
    }
}
  • constructor-arg参数:配置中使用这个constructor-arg标签ref属性注入引用类型对象
public class BookDaoImpl implements BookDao{
    private String databaseName;
    private int connectionNum;
    public BookDaoImpl(String databaseName,int connectionNum){
        this.databaseName=databaseName;
        this.connectionNum=connectionNum;
    }
    public void save(){
        System.out.println("123");
    }
}
//构造器注入
//property表示当前bean的属性
//name是形参的名字!!!!!!!!!!!(跟着传给函数中的形参走)
<bean id="bookDao" class="com.itheima.service.impl.bookDaoImpl">
    <constructor-arg name="databaseName" value="mysql"/> 
    <constructor-arg name="connectionNum" value="10"/> 
	//解决形参变化以及参数类型重复的问题,不耦合了。index表示上面变量名的顺序
    //<constructor-arg index="0" value="mysql"/> 
    //<constructor-arg index="1" value="10"/> 
</bean>
<bean id="userDao" class="com.itheima.service.impl.userDaoImpl">
<bean id="bookService" class="com.itheima.service.impl.bookServiceImpl">
    <constructor-arg name="bookDao1" ref="bookDao"/>   //name是形参的名字!!!!!!!!!!!
    <constructor-arg name="userDao1" ref="userDao"/>   
</bean>

5.3依赖自动注入装配

  • ioc容器根据bean所依赖的资源在容器中自动查找并注入到bean过程中
  • 自动装配方式:(需要set提供方法setBookDao!!!!!!!)
    • 按类型(常用):必须保障容器中相同类型的bean唯一
    • 按名称:必须保障容器中具有指定名称的bean,因变量名和配置耦合。
    • 按构造方法
    • 不启用自动装配
//autowire自动装配
<bean id="bookService" class="com.itheima.service.impl.bookServiceImpl" autowire="byType" />

5.4集合注入

数组,list,map,set,properties

//setter注入
<bean id="bookDao" class="com.itheima.service.impl.BookDaoImpl">
    <property name="arrayname">
    	<array>
    		<value>100</value>
    		<value>200</value>
    		<value>300</value>
    	</array>
    </property>
    <property name="listname">
    	<list>
    		<value>100</value>
    		<value>200</value>
    		<value>300</value>
    	</list>
    </property>
    <property name="setname">
    	<set>
    		<value>a</value>
    		<value>b</value>
    		<value>c</value>
    	</set>
    </property>
    <property name="mapname">
    	<map>
    		<entry key="country" value="china"/>
    		<entry key="province" value="jiangsu"/>
    		<entry key="city" value="yangzhou"/>
    	</map>
    </property>
    <property name="propertiesname">
    	<props>
    		<prop key="country">china</prop>
    		<prop key="province">jiangsu</prop>
    		<prop key="city">yangzhou</prop>
    	</props>
    </property>
</bean>

5.5 properties加载

  • 开启context命名空间
<?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文件
<context:property-placeholder location="classpath*:*.properties"/> //加载类路径或jar包下的所有properties文件
  • 使用${}读取加载的属性值
<bean class="com.alibaba.druid.pool.DruidDataSource">
	<property name="username" value="${jdbc.username}"/>
</bean>

6. 容器

从文件系统下加载配置文件:

FileSystemApplicationContext(”绝对路径“)

//之前的方法
//ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//BookService bookService = (BookService) ctx.getBean("bookService")
//bookService.save();
//文件系统下加载配置文件
ApplicationContext ctx = new FileSystemApplicationContext("D:\\workspace\\applicationContext.xml");//绝对路径!!
BookService bookService = ctx.getBean("bookService",bookService.class)
BookService bookService = ctx.getBean(bookService.class)//按类型找,容器中只能有一个bean
bookService.save();

BeanFactory是所有容器类的顶层接口

BeanFactory创建完毕后,所有的bean均为延迟加载

7. 注解开发

==需要在xml文件中加入context:annotation-config ,这是用来开启注解的支持,如果不加上注解就无效。

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config/>
</beans>
7.1 Component
  • 使用@Component定义bean
@Component("bookDao")
public class BookDaoImpl implements BookDao{
}
@Component   //与上面的区别是没有起一个名称Id,后面ctx.getBean()的时候只能传递类参数,而不能传递名称
public class BookServiceImpl implements BookService{
}
  • 核心配置文件中通过组件扫描加载bean
<context:component-scan base-package="com.itheima"/>

Spring提供@Component三个衍生注解:

1.@Controller:用于表现层bean定义

2.@Service:用于业务层bean定义

3.@Repository:用于数据层bean定义

@Controller  
@Service
@Repository
@Component("bookDao")
@Service("bookDao")
@Repository("bookDao")
public class BookServiceImpl implements BookService{
}
7.2 纯注解开发
7.2.1 Configuration

@Configuration:用于设定当前类为配置类

==@ComponentScan(“com.itheima”):==用于设定扫描路径,此注解只能添加一次。可以在新建的类离里替代<context:component-scan base-package=“com.itheima”/>

@Configuration
@ComponentScan("com.itheima")
public class SpringConfig{
}
  • 加载配置类初始化容器:
//原来的写法ApplicationContext ctx = new ClassPathXmlApplicaionContext(SpringConfig.class)
ApplicationContext ctx = new AnnotationConfigApplicaionContext(SpringConfig.class)
7.2.2 注解Bean生命周期
@Repository
@Scope("singleton")//单例
public class BookDaoImpl implements BookDao {
    public void save(){
		System.out.println("book dao save ...");
    }
    @PostConstruct//构造方法后运行的方法
	public void init(){
		System.out.println("book init ...");
    }
    @PreDestory//彻底销毁前构造的方法
	public void destory(){
		System.out.println("book destory ...");
    }
}
7.2.3 自动装配

@Autowired //自动装配

@Qualifier(“bookDao2”):指定加载的bean的名称,并且qualifier依赖Autowired

@PropertySource(“jdbc.properties”)//写在配置文件类里的。加载properties文件

@Service
public class BookServiceImpl implements BookService{
    @Autowired//自动装配
    @Qualifier("bookDao2")//指定加载的bean的名称,并且qualifier依赖Autowired
    @Value("itheima")//注入值类型
    @Value(${jdbc.name})//注入值类型
    private String Name;
    private BookDao bookDao;
    public void save(){
        System.out.println("book service save ...");
        bookDao.save();
    }
}
7.2.4 第三方bean管理

@Bean:表示当前方法的返回值式一个bean。

第一种方式:导入式

//不需要@Configuration!!!!!!
public class Jdbcconfig {
	@Bean
	public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();//相关配置
		return ds;
    }
}
//使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式
@Configuration
@Import(JdbcConfig.class)
public class Springconfig {
}

第二种方式:扫描式(不推荐)

@Configuration
public class Jdbcconfig {
	@Bean
	public DataSource datasource(){
        DruidDataSource ds =new DruidDataSource();//相关配置
		return ds;
    }
}

//使用@componentscan注解扫描配置类所在的包,加载对应的配置类信息
@Configuration
@ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"})
public class Springconfig {
}
7.2.5 第三方bean依赖注入
  • 简单类型:
public class Jdbcconfig {
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String userName;
    @Value("password")
    private String pässword;
    @Bean
    public DataSource datasource(){
        DruidDataSource ds=new DruidDataSource(); 		
        ds.setDriverclassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
  • 引用类型:
@Bean
public DataSource dataSource(BookService bookService){
    System.out.println(bookService);
    DruidDataSource ds=new DruidDataSource();//属性设置
	return ds;
}

引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

7.3 xml配置和注解的比较
功能xml配置注解
定义beanbean标签 id属性 class 属性@Component @Controller @Service @Repository @ComponentScan
设置依赖注入setter注入 构造器注入 自动装配@Autowired @Qualifier @Value
配置第三方beanbean标签 静态工厂 实例工厂 FactoryBean@Bean
作用范围scope属性@Scope
生命周期标准接口 init-method destroy-method@PostConstructor @PreDestroy

8. Spring整合MyBatis(将mybatis的xml配置文件整合)

  • SqlSessionFactoryBean
  • MapperScannerConfigurer
public class Mybatisconfig {
	@Bean
	public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb=new SqlSessionFactoryBean();
        /*
        <typeAliases>
			<package name="com.itheima.domain"/>
		</typeAliases)
        */
        ssfb.setTypeAliasesPackage("com.itheima.domain");
        /*
        <dataSource type="POOLED">
        	<property name="driver" value="${jdbc.driver}"></property>
        	<property name="url" value="${jdbc.url}"></property>
        	<property name="username" value="${jdbc.username}"></property>
        	<property name="password" value="${jdbc.password}"></property>
        </dataSource>
        */
        ssfb.setDataSource(dataSource);
        return ssfb;
    }
    /*
    <mappers>
		<package name="com.itheima.dao"></package>
	</mappers>
	*/
	@Bean
	public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc=new MapperScannerConfigurer();
        msc.setBasePackage("com.itheima.ao");
        return msc;
    }
}

9. Spring整合Junit

@RunWith:设定专用的类运行器

@ContextConfiguration:指定spring上下文运行的配置类

@RunWith(springJUnit4classRunner.class)
@Contextconfiguration(classes =SpringConfig.class)
public class BookServiceTest {
	@Autowired
	private BookService bookService;
	@Test
	public void testSave(){
        bookService.save();
    }
}

10. AOP:面向切面编程

10.1 定义

  • 作用:在不惊动原始设计的基础上为其进行功能增强
  • Spring理念,无入侵式
  • 连接点:在AOP中理解为方法的执行
  • 切入点:一个切入点描述一个具体方法,也可以匹配多个方法。
    • 一个具体方法:com.itheima.dao包下的BookDao接口中的无形参无返回值的save方法
    • 匹配多个方法:所有save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法
  • 通知(共性功能):功能最终以方法的形式呈现
  • 通知类:定义通知的类
  • 切面:描述通知与切入点的对应关系

10.2 入门案例

  • 思路分析

    • 导入坐标(pom.xml)
    • 制作连接点方法(原始操作,Dao接口与实现类)
    • 制作共性功能(通知类喝通知)
    • 定义切入点(@Pointcut(“execution(void com.itheima.dao.BookDao.update())”))
    • 绑定切入点与通知关系(切面)

@Aspect:把MyAdvice的bean当作一个AOP来处理

@EnableAspectJAutoProxy:这句话启动了通知类里的@Aspect。告诉Spring用到注解开发的AOP

@Before(“pt()”):绑定切入点和通知

@Component
@Aspect//把MyAdvice的bean当作一个AOP来处理。启动了下列的@Pointcut @Before
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}
	@Before("pt()")//绑定切入点和通知
    public void method(){
		System.out.println(System.currentTimeMillis());
    }
}
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy//这句话启动了通知类里的@Aspect。告诉Spring用到注解开发的AOP
public class SpringConfig{
}

10.3 AOP工作流程

目标对象:原始功能去掉共性功能对应的类产生的对象,这种对象式无法直接完成最终工作的

代理:目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现

  • Spring容器启动
  • 读取所有切面配置中的切入点
  • 初始化bean,判定bean对应的类中的方法是否匹配到任意切入点
    • 匹配失败,创建对象
    • 匹配成功,创建原始对象(目标对象)的代理对象
  • 获取bean执行方法
    • 获取bean,调用方法并执行,完成操作
    • 获取的bean式代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

10.4 切入点表达式

  • 切入点:要进行增强的方法
  • 切入点表达式:要进行增强的方法的描述方式
  • 切入点表达式标准规则:动作关键字(访问修饰符 返回值 包名.类/接口.方法名(参数)异常名)
execution(public User com.itheima.service.UserService.findById(int))
  • 可以使用通配符描述切入点,快速描述

    • *:单个独立的符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现。必有一个

      execution(public * com.itheima.&.UserService.find*(*))
      //匹配com.itheima包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法
      
    • …:多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写。任意

    execution(public User com..UserService.findById(..))
    //匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法
    

10.5 AOP通知类型

  • 前置通知
@Before("pt()")
public void method(){System.out.println(1);}
//输出为:
//      1
//		pt()
  • 后置通知
@after("pt()")
public void method(){System.out.println(1);}
//输出为:
//      pt()
//		1
  • 环绕通知

    注意事项:

    • 环绕必须依赖形参:ProceedingJoinPoint才能实现对原始方法的调用
    • 如果没有使用ProceedingJoinPoint对原始方法的调用将跳过原始发放的执行
    • 对原始方法的调用可以不接受返回值,通知方法设置成void即可,如果接受返回值必须设定为Object类型返回值
    • 原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void也可以设置成Object
    • 由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象
@Around("pt()")
public Object method(ProceedingJoinPoint pjp) throw Throwable{
    System.out.println("before");
    //表示对原始操作的调用
    Object ret = pjp.proceed();
    System.out.println("after");
    return ret
}
//输出为:
//		before
//		pt()的返回值
//		after
  • 返回后通知

@AfterReturning

  • 抛出异常后通知

@AfterThrowing

10.6 AOP通知获取数据

JointPoint参数

ProceedJointPoint是JoinPoint的子类

  • AOp通知获取参数数据
@Before("pt()")
public void before(JoinPoint jp){
    object[] args = jp.getArgs();
    System.out.println(Arrays.tostring(args));
}
@Around("pt()")
public Object around(ProceedingJoinPoint pjp)throws Throwable {
    Object[] args =pjp.getArgs();
    System.out.println(Arrays.tostring(args));
    Object ret = pjp.proceed();
	return ret;
}
/*
@Around("pt()")
public Object around(ProceedingJoinPoint pjp)throws Throwable {
    Object[] args =pjp.getArgs(); //假设args[0]是100
    System.out.println(Arrays.tostring(args));
    args[0] = args[0]+566;
    Object ret = pjp.proceed(args[0]);
	return ret;
}
返回值args[0]是100+566-->666
  • AOP通知获取返回值参数
//抛出异常后通知可以获取切入点方法中出现的异常信息,使用形参可以接受对应的异常对象
@AfterReturning(value ="pt()",returning ="ret")
public void afterReturning(string ret){
    System.out.println("afterReturning advice ..."+ret);
}
//环绕通知中可以手工书写对原始方法的调用,得到的结果即为原始方法的返回值
@Around("pt()")
public Object around(ProceedingJoinPoint pip) throws Throwable {
    Object ret = pjp.proceed();
	return ret;
}

11 事务

11.1 事务介绍

  • 主要流程

    • @Transactional:在业务接口(也可以在接口类上)上添加Spring事务管理(通常不会加到业务层实现类中)
    public interface PlatformTransactionManager(){
        @Transactional
        public void transfer(String out,String in,Double money)
    }
    
    • 设置事务管理器
    //DataSourceTransactionManager Spring提供的接口
    @Bean
    public class DataSourceTransactionManager(Datasource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
    
    • 开启注解式事务驱动
    @Configuration
    @ComponentScan("com.itheima")
    @PropertySource("jdbc.properties")
    @Import({JdbcConfig.class,MybatisConfig.class})
    @EnableTransactionManagement//告诉配置文件使用注解事务
    public class SpringConfig{
    }
    
  • 事务作用:在数据层保障一系列的数据库操作同成功同失败

  • Spring事务作用:在数据或业务层保障一系列的数据库操作同成功同失败

11.2 事务角色

  • 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
  • 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以式业务层的方法

11.3 事务配置

@Transactional(readOnly = true,timeout=-1)//只读,永不超时
@Transactional(rollbackFor = {IOException.class})//遇到IOException异常就回滚(有的事务不一定会回滚)
  • 事务传播行为:事务协调员对事务管理员所携带事物的处理态度
@Transactional(propagation = Propagation.REQUIRES_NEW)//不管转账有没有成功,都会执行日志操作。事务管理员开启事务T,事务协调员新建事务T2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值