1. Spring知识总结,学习复习笔记

Spring

引言:小编也在努力学习的过程中,如果hxd们有什么建议或者错误纠正,请联系我哦

注意:本篇文章有大量的代码,都放在下载包里 点击下载

参考文档:Spring Framework Documentation

文章目录

  • Spring
    • 1、Spring
      • 1. 1、简介
      • 1.2、优点
      • 1.3、组成
      • 1.4、拓展
    • 2、IOC理论推导
    • 3、HelloSpring
    • 4、IOC 创建对象的方式
    • 5、Spring配置
      • 5.1、别名
      • 5.2、Bean的配置
      • 5.3、import
    • 6、DI 依赖注入
      • 6.1、构造器注入
      • 6.2、通过set注入【重点】
      • 6.3、拓展方式注入
      • 6.4、bean的作用域
    • 7、bean的自动装配
      • 7.1、测试
      • 7.2、ByName 自动装配
      • 7.3、ByType 自动装配
      • 7.4、使用注解实现自动装配
    • 8、使用注解开发
    • 9、使用 java 的方式配置Spring
    • 10、代理模式
      • 10.1、静态代理
      • 10.2、加深理解
      • 10.3、动态代理
    • 11、AOP
      • 11.1、什么是 AOP
      • 11.2、AOP 在 Spring 中的作用
      • 11.3、使用 Spring 实现 AOP
    • 12、整合Mybatis
      • 12.1、回忆Mybatis
      • 12.2、Mybatis-spring
    • 13、声明式事务
      • 13.1、回顾事务
      • 13.2、Spring 中的事务管理

1、Spring

1. 1、简介

  • 2002, 首次推出了Spring框架的雏形:interface21框架

  • Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵

  • Rod Johnson,Spring Framework创始人

  • Spring理念:是现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!

  • SSH:Struct2 + Spring + Hibernate!

  • SSM:SpringMVC + Spring + Mybatis!

  • 官网:Spring Framework

  • 下载地址:repo.spring.io

  • maven 导包


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.3.9version>
dependency>
可能会用到这个,一般不用

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-jdbcartifactId>
    <version>5.3.8version>
dependency>

1.2、优点

  • Spring是一个开源的免费的容器(框架)!
  • Spring是一个轻量级的、非入侵式的框架!
  • 控制反转(IOC),面向切面编程(AOP)!
  • 支持事务的处理,对框架的支持!

总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

1.3、组成

有七大模块。

1.4、拓展

  • Spring Boot

    • 一个快速开发的脚手架
    • 基于SpringBoot可以快速的开发单个微服务
    • 约定大于配置!
  • Spring Cloud

    • Spring Cloud是基于SpringBoot实现的

2、IOC理论推导

看代码spring-01

理解可以看Spring:IOC本质分析探究 - 灰信网(软件开发博客聚合) (freesion.com)

控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

1. Spring知识总结,学习复习笔记_第1张图片

3、HelloSpring

参照代码spring-02-hellospring

4、IOC 创建对象的方式

参照代码spring-03-ioc2

  1. 使用无参构造创建对象

  2. 使用有参构造创建对象

    1. 下标赋值

      
          <bean id="user" class="com.la.pojo.User">
              <constructor-arg index="0" value="000LA"/>
          bean>
      
    2. 通过类型创建

      
      <bean id="user" class="com.la.pojo.User">
              <constructor-arg type="java.lang.String" value="11111LA"/>
          bean>
      
      1. 通过参数名来设值
      
          <bean id="user" class="com.la.pojo.User">
              <constructor-arg name="name" value="LAb"/>
          bean>
      

​ 总结:在配置文件加载的时候,容器中的管理的对象就已经初始化了

5、Spring配置

参照代码spring-03-ioc2

5.1、别名


    <alias name="user" alias="userNew"/>

5.2、Bean的配置


    <bean id="userT" class="com.la.pojo.UserT" name="t uT2">
        
    bean>

5.3、import

这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个

假设项目中有多个人开发,这三个人有不同的开发,不同的类需要注册在不同的bean中,我门可以用import将所有的beans.xml合并为一个总的

6、DI 依赖注入

参照代码spring-04-di

6.1、构造器注入

前面说过了

6.2、通过set注入【重点】

  • 依赖注入:Set注入
    • 依赖:bean对象的创建依赖于容器!
    • 注入:bean对象中的所有属性,有容器来注入!

【环境搭建】

  1. 复杂类型

    public class Address {
    
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  2. 真实测试对象

    public class Student {
    
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobby;
        private Map<String, String> card;
        private Set<String> games;
        private Properties info;
        private String wife;
    }
    
  3. beans.xml

    
    <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">
    
        <bean id="student" class="com.la.pojo.Student">
    
            <property name="name" value="LA"/>
        bean>
    
    beans>
    
  4. 测试类

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) context.getBean("student");
            System.out.println(student.getName());
        }
    }
    
  5. 完善后的beans.xml

    
    <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">
    
        <bean id="address" class="com.la.pojo.Address">
            <property name="address" value="西安"/>
        bean>
    
        <bean id="student" class="com.la.pojo.Student">
    
            <property name="name" value="LA"/>
    
    
            <property name="address" ref="address"/>
    
    
            <property name="books">
                <array>
                    <value>红楼梦value>
                    <value>水浒传value>
                    <value>西游记value>
                    <value>三国演义value>
                array>
            property>
    
    
            <property name="hobby">
                <list>
                    <value>听歌value>
                    <value>敲代码value>
                    <value>看电影value>
                list>
            property>
    
    
            <property name="card">
                <map>
                    <entry key="身份证" value="123456123456"/>
                    <entry key="银行卡" value="620014214552"/>
                map>
            property>
    
    
            <property name="games">
                <set>
                    <value>LOLvalue>
                    <value>COCvalue>
                set>
            property>
    
    
            <property name="wife">
                <null/>
            property>
    
    
            <property name="info">
                <props>
                    <prop key="学号">2019151352prop>
                    <prop key="性别">prop>
                    <prop key="姓名">小明prop>
                props>
            property>
    
        bean>
    
    
    beans>
    

6.3、拓展方式注入

我们可以使用 P 命名空间和 C 命名空间进行注入

官方解释:

1. Spring知识总结,学习复习笔记_第2张图片

1. Spring知识总结,学习复习笔记_第3张图片

  1. 使用:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="user" class="com.la.pojo.User" p:name="LA" p:age="18"/>


    <bean id="user2" class="com.la.pojo.User" c:name="leon" c:age="18"/>

beans>
  1. 测试:

        @Test
        public void test2() {
            ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
    
    //        User user = context.getBean("user", User.class);
    //        System.out.println(user);
    
            User user2 = context.getBean("user2", User.class);
            System.out.println(user2);
        }
    }
    

    注意点:

    P 命名 和 C 命名空间不能直接使用,需要导入xml约束!

    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    

6.4、bean的作用域

1. Spring知识总结,学习复习笔记_第4张图片

  1. 单例模式(Spring默认机制)

    
        <bean id="user2" class="com.la.pojo.User" c:name="leon" c:age="18" scope="singleton"/>
    
  2. 原型模式,每次从容器中 get 的时候,都会产生一个新对象!

        
        <bean id="user2" class="com.la.pojo.User" c:name="leon" c:age="18" scope="prototype"/>
    
  3. 其余的 request,session,application,这些都在能在 web 开发中使用

7、bean的自动装配

  • 自动装配是 Spring 满足 bean 依赖的一种方式
  • Spring 会在上下文中自动寻找,并自动给 bean 装配属性

在 Spring 中有三种装配的方式

  1. 在 xml 中显示的配置
  2. 在 java 中显示的配置
  3. 隐式的自动装配 bean【重要】

7.1、测试

环境搭建:一个人有两个宠物!

代码:spring-05-Autowired

7.2、ByName 自动装配


<bean id="people" class="com.la.pojo.People" autowire="byName">
    <property name="name" value="LA"/>
bean>

7.3、ByType 自动装配


<bean id="people" class="com.la.pojo.People" autowire="byType">
    <property name="name" value="LA"/>
bean>

小结:

  • ByName 的时候,需要保证所有 bean 的 id 唯一,并且这个 bean 需要和自动注入的属性的 set 方法的值一致!
  • ByType 的时候,需要保证所有 bean 的 class 唯一,并且这个 bean 需要和自动注入的属性的类型一致!

7.4、使用注解实现自动装配

jdk1.5支持的注解,Spring2.5就支持注解

要使用注解须知:

  1. 导入约束 。context 约束 : xmlns:context="http://www.springframework.org/schema/context"

  2. 配置注解的支持: 【重要】

    
    <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>
    

@Autowired

直接在属性上使用即可!也可以在 set 方式上使用

使用 AutoWired 我们可以不用编写 Set 方法了,前提是你这个自动装配的属性在 IOC (Spring) 容器中存在,且符合名字

注意:Autowire默认按照类型装配(即ByType),默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,如果我们想使用按照名称装配(ByName),可以结合@Qualifier注解一起使用;

@Autowired是按照先byType 后 byName @Resources是按照先byName后byType((12条消息) @Resource注解的官方解释_cherry的博客-CSDN博客_@resource注解)

科普:

@Nullable  字段标记了这个注解,说明这个字段可以为null

如果定义了 Autowired 的 required 属性为 false ,说明这个对象可以为 null,否则不为空

public class People {
// 如果定义了 Autowired 的 required 属性为 false ,说明这个对象可以为 null,否则不为空
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;

8、使用注解开发

参照代码spring-06-anno

Spring 4 之后要使用注解开发,必须要保证 aop 的包导入了

在使用注解需要导入 context 约束,增加注解的支持

@Component : 组件, 放在类上,说明这个类被Spring管理了,就是bean
  1. bean

  2. 属性如何注入

    // 等价于 
    //     @Component 组件
    @Component
    public class User {
    
        // 相当于 
        @Value("LA")
        public String name;
        
        // 或者 value 使用在 setName 上也是可以给属性赋值
        @Value("LA")
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
  3. 衍生的注解

    @Component 有几个衍生的注解,我们在 web 开发中,会按照 MVC 三层架构分层!

    • dao 【@Repository】

    • service 【@Service】

    • controller 【@Controller】

      这四个注解功能相同,都是代表将某个类注册到 Spring 容器中装配,也就是装配 bean

  4. 自动装配注解

    • @Autowired : 自动装配通过类型,名字
      • 如果Autowired不能唯一自动装配上属性,则通过@Qualifier(value=“xxx”)
    • @Resource :自动装配通过名字,类型
  5. 作用域

    单例模式和原型模式

    // 等价于 或者使用singleton 
    @Scope("prototype")
    @Component
    public class User {
    
        // 相当于 
        @Value("LA")
        public String name;
        
        // 或者 value 使用在 setName 上也是可以给属性赋值
        @Value("LA")
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
  6. 小结

xml 与 注解:

  • xml 更加万能,适用于任何场合,维护简单方便
  • 注解 不是自己的类,使用不了,维护相对复杂

xml 与 注解的最佳实践:

  • xml用来管理bean
  • 注解只负责所有的属性的注入
  • 我们在使用的过程中,只需要注意一个问题,必须让注解生效,就需要开启注解的支持

9、使用 java 的方式配置Spring

参照代码spring-07-appConfig

我们现在要完全不使用 Spring 的 xml 配置了,全权交给 java 来做

JavaConfig 是 Spring 的一个子项目,在 Spring4 之后,它成为了一个核心功能

实体类

// 这里注解的意思,就是说明这个类被Spring接管了,注册到了容器中
@Component
public class User {

    @Value("LA") // 属性注入值
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

配置文件类

// @Configuration 代表这是一个配置类,就和我们之前看到beans.xml一样
// 这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@Component
@Configuration
@ComponentScan("com.la")
@Import(MyConfig2.class)
public class MyConfig {

    // 注册一个bean,就相当于之前写的一个bean标签
    // 这个方法的名字就相当于bean标签的id属性
    // 这个方法的返回值就相当于bean标签中的class属性
    @Bean
    public User getUser() {
        return new User(); // 就是返回要注入到bean的对象
    }

}
@Configuration
public class MyConfig2 {
}

测试类

public class MyTest {
    public static void main(String[] args) {
        // 如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的 class 对象加载
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

        User getUser = (User) context.getBean("getUser");

        System.out.println(getUser.getName());
    }
}

这种纯 java 的配置方式,在SpringBoot中随处可见

10、代理模式

为什么要学习代理模式? 因为这就是 SpringAOP 的底层 【SpringAOP 和 SpringMVC】

代理模式的分类:

  • 静态代理
  • 动态代理

参照代码spring-08-proxy

10.1、静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
  • 客户:访问代理对象的人

代码步骤:

  1. 接口

    // 租房的接口
    public interface Rent {
    
        public void rent();
    
    }
    
  2. 真实角色

    // 房东
    public class Host implements Rent{
    
        @Override
        public void rent() {
            System.out.println("房东要出租房子!");
        }
    }
    
  3. 代理角色

    // 代理,中介
    public class Proxy implements Rent{
    
        private Host host;
    
        public Proxy() {
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        @Override
        public void rent() {
            seeHouse();
            host.rent();
            heTong();
            fare();
        }
    
        // 看房
        public void seeHouse() {
            System.out.println("中介带你看房");
        }
    
        //
        public void heTong() {
            System.out.println("签租赁合同");
        }
    
        // 收中介费
        public void fare() {
            System.out.println("收中介费");
        }
    
    }
    
    
  4. 客户端访问代理角色

    // 用户
    public class Client {
        public static void main(String[] args) {
            // 房东要租房子
            Host host = new Host();
            // 代理,中介帮房东租房子,但代理角色一般会有一些附属操作
            Proxy proxy = new Proxy(host);
            // 你不用面对房东,直接找中介租房子
            proxy.rent();
        }
    }
    
    

代理模式的好处:

  • 可以使真实角色的操作更加纯粹,不用关注一些公共的业务
  • 公共也就交给代理角色,实现了业务的分工
  • 公共业务发生扩展的时候,方便集中管理

缺点:

  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低

10.2、加深理解

代码:spring-08-proxy中的demo2

聊聊AOP:

1. Spring知识总结,学习复习笔记_第5张图片

10.3、动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的!
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口-----JDK动态代理【我们在这里使用】
    • 基于类:cglib
    • java字节码实现:javassist

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

动态代理的好处:

  • 可以使真实角色的操作更加纯粹,不用关注一些公共的业务
  • 公共也就交给代理角色,实现了业务的分工
  • 公共业务发生扩展的时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般都是对应的一类业务
  • 一个动态代理类,可以代理多个类,只要是实现了同一个接口即可

11、AOP

11.1、什么是 AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

11.2、AOP 在 Spring 中的作用

提供声明式事务;允许用户自定义切面

  • 横切关注点:跨越应用程序多个模块的方法或功能。即,与我们的业务无关,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等…
  • 切面(Aspect):横切关注点被模块化的特殊对象,即,它是一个类
  • 目标(Target):切面必须要完成的工作。即,它是类中的一个方法
  • 代理(Proxy):被通知对象
  • 切入点(PointCut):切面通知执行的“地点”的定义
  • 连接点(JointPoint):与切入点匹配的执行点

SpringAOP 中,通过Advice定义横切逻辑,Spring 中支持5种类型的 Advice :

通知类型 连接点 实现接口
前置通知 方法方法前 org.springframework.aop.MethodBeforeAdvice
后置通知 方法前 org.springframework.aop.AfterReturningAdvice
环绕通知 方法后 org.aopalliance.intercept.MethodInterceptor
异常抛出通知 方法抛出异常 org.springframework.aop.ThrowsAdvice
引介通知 类中增加新的方法属性 org.springframework.aop.IntroductionInterceptor

即 AOP 在不改变原有代码的情况下,去增加新功能

11.3、使用 Spring 实现 AOP

【重点】使用 AOP 织入,需要导入一个依赖包!


<dependency>
    <groupId>org.aspectjgroupId>
    <artifactId>aspectjweaverartifactId>
    <version>1.9.7version>
    <scope>runtimescope>
dependency>

方式一:使用 Spring 的 API 接口【主要SpringAPI接口实现】

参照代码spring-09-aop的log

方式二:自定义类来实现AOP【主要是切面定义】

参照代码spring-09-aop的diy

方式三:使用注解实现

参照代码spring-09-aop的diy

12、整合Mybatis

步骤:

  1. 整合相关 jar 包

    • Junit

    • mybatis

    • mysql数据库

    • spring相关的

    • aop织入

    • mybatis-spring【new】官方文档 mybatis-spring –

      <dependencies>
          <dependency>
              <groupId>org.springframeworkgroupId>
              <artifactId>spring-webmvcartifactId>
              <version>5.3.9version>
          dependency>
      
          <dependency>
              <groupId>org.junit.jupitergroupId>
              <artifactId>junit-jupiter-apiartifactId>
              <version>5.7.2version>
          dependency>
          <dependency>
              <groupId>mysqlgroupId>
              <artifactId>mysql-connector-javaartifactId>
              <version>8.0.25version>
          dependency>
      
          <dependency>
              <groupId>org.mybatisgroupId>
              <artifactId>mybatisartifactId>
              <version>3.5.7version>
          dependency>
      
          
          <dependency>
              <groupId>org.springframeworkgroupId>
              <artifactId>spring-jdbcartifactId>
              <version>5.3.9version>
          dependency>
      
          <dependency>
              <groupId>org.aspectjgroupId>
              <artifactId>aspectjweaverartifactId>
              <version>1.9.7version>
          dependency>
      
          <dependency>
              <groupId>org.mybatisgroupId>
              <artifactId>mybatis-springartifactId>
              <version>2.0.6version>
          dependency>
      
      dependencies>
      
  2. 编写配置文件

  3. 测试

12.1、回忆Mybatis

参照代码spring-10-mybatis

  1. 编写实体类
  2. 编写核心配置文件
  3. 编写接口
  4. 编写Mapper.xml
  5. 测试

12.2、Mybatis-spring

参照代码中的UserMapper,UserMapperImpl,UserMapper.xml,applicationConfig.xml,mybatis-config.xml,spring-dao.xml,MyTest中的test以及selectUser

  1. 编写数据源配置
  2. sqlSessionFactory
  3. sqlSessionTemplate
  4. 需要接口加实现类
  5. 将写的实现类,注入到spring中
  6. 测试使用

13、声明式事务

13.1、回顾事务

  • 把一组业务当成一个业务来做,要么都成功,要么都失败
  • 在项目开发中十分重要,涉及到数据的一致性问题
  • 确保完整性和一致性

事务的 ACID 原则:

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能操作同一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会发生影响,被持久化的写到存储器中

13.2、Spring 中的事务管理

参照代码spring-11-transaction

  • 编程式事务:需要在代码中进行事务的管理
  • 声明式事务:AOP

在这个代码中:

  1. 我们采用配置声明式事务并结合AOP实现事务的织入

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <constructor-arg ref="dataSource" />
bean>



<tx:advice id="txAdvice" transaction-manager="transactionManager">
    
    
    <tx:attributes>
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="update" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="query" read-only="true"/>
        <tx:method name="*" propagation="REQUIRED"/>
    tx:attributes>
tx:advice>


<aop:config>
    <aop:pointcut id="txPointCut" expression="execution(* com.la.dao.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
aop:config>
  1. 将代码中的删除代码写错,来进行测试,【注意】这里代码保留这条错误

    1. Spring知识总结,学习复习笔记_第6张图片

测试发现,当不使用配置事务的时候,数据库中会添加上数据,却不会删除这条数据

但是配置事务后,数据库不会添加上数据。

为什么需要事务

  • 如果不配置事务,可能存在数据提交不一致的情况下;
  • 如果不在spring中配置声明式事务,我们就需要在代码中手动配置事务
  • 事务在项目中的开发十分重要,涉及到数据的一致性和完整性问题,不容马虎

你可能感兴趣的:(后端,spring,java)