spring集成mybatis框架

前言

将 MyBatis与 Spring 进行整合,主要解决的问题就是将 SqlSessionFactory 对象交由 Spring来管理。所以,该整合只需要将 SqlSessionFactory 的对象生成器 SqlSessionFactoryBean 注册在 Spring 容器中,再将其注入给 Dao 的实现类即可完成整合。

MyBatis与 Spring 进行整合使用的技术是:ioc

为什么ioc能把mybatis和spring集成在一起,像一个框架一样的使用:这是因为ioc能创建对象,可以把mybatis框架中的对象交给spring统一创建, 开发人员从spring中获取对象,不用同时面对两个或多个框架了, 就面对一个spring进行开发。

在这里插入图片描述

一、回顾mybatis的使用步骤

mybatis使用步骤:
1.导入相关的依赖
2.编写实体类
3.定义dao接口 ,StudentDao
4.定义mapper文件 StudentDao.xml
5.定义mybatis的主配置文件 mybatis.xml
6.创建dao的代理对象,并调用方法

	StudentDao dao = SqlSession.getMapper(StudentDao.class);
	List<Student> students  = dao.selectStudents();

要使用dao对象,需要使用getMapper()方法,使用getMapper()方法需要哪些条件:
1.获取SqlSession对象, 需要使用SqlSessionFactory的openSession()方法。
2.创建SqlSessionFactory对象。 通过读取mybatis的主配置文件,能创建SqlSessionFactory对象
3.通过SqlSessionFactory对象, 使用factory能获取SqlSession ,有了SqlSession就能有dao , 目的就是获取dao对象。factory创建需要读取主配置文件的。

在这里插入图片描述

主配置文件:
1.数据库信息

<environment id="mydev">
   <transactionManager type="JDBC"/>
     <dataSource type="POOLED">
         <!--数据库的驱动类名-->
         <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
         <!--连接数据库的url字符串-->
         <property name="url" value="jdbc:mysql://localhost:3306/数据库名"/>
         <!--访问数据库的用户名-->
         <property name="username" value="root"/>
         <!--密码-->
         <property name="password" value="123456"/>
     </dataSource>
</environment>          

代码中的dataSource type="POOLED"表示数据源类型的连接池,该连接池是mybatis自带的,他的性能比较弱,一般不在大型项目中使用。在大型项目中会使用独立的连接池类(阿里的druid连接池)替换mybatis默认自己带的, 把连接池类也交给spring创建。

2.mapper文件的位置

   <mappers>
        <mapper resource="com/xzz/dao/StudentDao.xml"/>
        <!--<mapper resource="com/xzz/dao/SchoolDao.xml" />-->
    </mappers>

通过以上的说明,我们需要让spring创建以下对象:
1.独立的连接池类对象, 使用阿里的druid连接池
2.SqlSessionFactory对象
3.创建出dao对象

需要学习就是上面三个对象的创建语法,使用xml的bean标签。

二、spring集成mybatis的步骤

2.1 步骤

1.新建maven项目
2.加入maven的依赖

1)spring依赖
2)mybatis依赖
3)mysql驱动
4)spring的事务的依赖
5)mybatis和spring集成的依赖: mybatis官方提供的,用来在spring项目中创建mybatis的SqlSesissonFactory,dao对象

3.创建实体类
在这里插入图片描述

4.创建dao接口和mapper文件(具体的数据库操作)
在这里插入图片描述

5.创建mybatis主配置文件
在这里插入图片描述

这里有两点需要注意:
(1)主配置文件中不再需要数据源的配置了。因为数据源要交给 Spring 容器来管理了(在application。properties文件中声明即可)。
(2)这里对 mapper 映射文件的注册,使用<package/>标签,即只需给出 mapper 映射文件所在的包即可。因为 mapper 的名称与 Dao 接口名相同,可以使用这种简单的注册方式。这种方式的好处是,若有多个映射文件,这里的配置也是不用改变的。当然,也可使用原来的<resource/>标签方式。

6.创建Service接口和实现类,属性是dao。
在这里插入图片描述

7.创建spring的配置文件:声明mybatis的对象交给spring创建

1)数据源DataSource
2)SqlSessionFactory
3) Dao对象
4)声明自定义的service

在这里插入图片描述

8.创建测试类,获取Service对象,通过service调用dao完成数据库的访问
在这里插入图片描述

2.2 什么是连接池

连接池:多个连接Connection对象的集合, List<Connection> connlist : connList就是连接池

通常使用Connection访问数据库

Connection conn =DriverManger.getConnection(url,username,password);
Statemenet stmt = conn.createStatement(sql);
stmt.executeQuery();
conn.close();

使用连接池
在程序启动的时候,先创建一些Connection

Connection c1 = ...
Connection c2 = ...
Connection c3 = ...
List<Connection>  connlist = new ArrayLits();
connList.add(c1);
connList.add(c2);
connList.add(c3);

Connection conn = connList.get(0);
Statemenet stmt = conn.createStatement(sql);
stmt.executeQuery();
把使用过的connection放回到连接池
connList.add(conn);


Connection conn1 = connList.get(1);
Statemenet stmt = conn1.createStatement(sql);
stmt.executeQuery();
把使用过的connection放回到连接池
connList.add(conn1);

2.3 编写spring的配置文件

从前面的步骤可以看到,要在spring的配置文件中声明交由spring创建管理的mybatis对象。

2.3.1 数据源的配置(掌握)

既然要把数据源交由spring创建,那么就应该在spring主配置文件中定义数据源的信息。数据源直接以 Bean 的形式配置在 Spring 配置文件中。根据数据源的不同,其配置方式不同。这里我使用的是比较流行的,排名也靠前的Druid 数据源 DruidDataSource。

什么是Druid ?
Druid 是阿里的开源数据库连接池。是 Java 语言中最好的数据库连接池。Druid 能够提供强大的监控和扩展功能。他有自己的官方网站,源代码在GitHub中。

官网:https://github.com/alibaba/druid/
DruidDataSource配置教程:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE

一切准备好后,在spring的主配置文件application.properties文件中添加配置信息
在这里插入图片描述

这里是将数据库有关的信息的抽取到数据库的属性配置文件中。Spring 配置文件从属性文件中读取数据时,需要在<property/>的 value 属性中使用${ },将在属性文件中定义的 key 括起来,以引用指定属性的值。

注意:
该属性文件若要被 Spring 配置文件读取,其必须在配置文件中使用<context>标签进行注册。

<context:property-placeholder/> 该方式要求在 Spring 配置文件头部加入 spring-context.xsd 约束文件。

2.3.2 注册 SqlSessionFactoryBean

在这里插入图片描述

2.3.3 定义 Mapper 扫描配置器MapperScannerConfigurer(创建dao对象)

Mapper 扫描配置器 MapperScannerConfigurer 会自动生成指定的基本包中 mapper 的代理对象。该 Bean 无需设置 id 属性。basePackage 使用分号或逗号设置多个包。

在这里插入图片描述
MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper()方法,得到每个接口的dao对象。创建好的dao对象放入到spring的容器中的。 dao对象的默认名称是 接口名首字母小写

2.3.4 向Service 注入接口名

因为在项目中是通过service来调用dao对象的,而不是操作接口的,因此需要将service的实现类加入到spring的容器中,并把dao对象赋值给service。
在这里插入图片描述
service实现类:
在这里插入图片描述
测试类:
在这里插入图片描述

2.3. Spring 配置文件全部配置

在这里插入图片描述

三、spring的事务处理

3.1 事务的基本概念

3.1.1 什么是事务

在mysql中提出了事务。 事务是指一组sql语句的集合, 集合中有多条sql语句,可能是insert , update ,select ,delete, 我们希望这些多个sql语句都能成功,或者都失败的执行。 这些sql语句的执行是一致的,作为一个整体执行。

3.1.2 在什么时候想到使用事务

当操作涉及得到多个表或者是多个sql语句的insert,update,delete时,需要保证这些语句都是成功才能实现某一个功能,或者都失败,保证操作是符合要求的。(比如ATM,取钱的操作,需要ATM吐钱和我的账户上金额同时减少对应的金额才算成功)

那么,在java代码中写程序控制事务处理,此时事务应该放在那里呢?
该事物应该在service实现类的业务方法上,因为业务方法会调用多个dao方法,执行多个sql语句。

使用事务的目的在于保证数据在每次访问或修改时都能保持一个相对准确的结果。事物的操作要么全部执行成功,要么全部执行失败。

3.1.3 通常使用JDBC访问数据库, 或者是mybatis访问数据库是怎么处理事务的

1.jdbc访问数据库,处理事务是通过
Connection conn ; conn.commit(); conn.rollback();

2.mybatis访问数据库,处理事务是通过
SqlSession.commit(); SqlSession.rollback();

3.hibernate访问数据库,处理事务是通过
Session.commit(); Session.rollback();

3.1.4 通常的事务处理方式,有什么不足

  • 不同的数据库访问技术,处理事务的对象、方法不同,需要了解不同数据库访问技术使用事务的原理
  • 需要掌握多种数据库中事务的处理逻辑。什么时候提交事务,什么时候回滚事务。
  • 要掌握处理事务的多种方法。

总结: 就是多种数据库的访问技术,有不同的事务处理的机制、对象和方法。

3.1.5 怎么解决不足

spring提供一种事务处理的统一模型, 能使用统一的步骤和方式完成多种不同数据库访问技术的事务处理。也就是说,把事务相关的资源和内容都提供给spring,spring会自动处理事务的提交、回滚,几乎不需要写代码。

使用spring的事务处理机制,可以完成mybatis访问数据库的事务处理,同时也可完成hibernate访问数据库的事务处理。
在这里插入图片描述

3.2 spring事务

3.2.1 spring的事务管理

事务原本是数据库中的概念,在 Dao 层。但一般情况下,需要将事务提升到业务层,即 Service 层。这样做是为了能够使用事务的特性来管理具体的业务。

在 Spring 中通常可以通过以下两种方式来实现对事务的管理:
(1)使用 Spring 的事务注解管理事务
(2)使用 AspectJ 的 AOP 配置管理事务

3.2.2 spring的事务处理

spring处理事务的模型,使用的步骤都是固定的,把事务使用的信息提供给spring就可以了。

1.spring事务内部提交,回滚事务,是通过事务管理器对象代替你完成commit,rollback。

1)事务管理器是一个接口和他的众多实现类。
2)接口:PlatformTransactionManager ,定义了事务的重要方法 commit ,rollback。
3)实现类:spring把每一种数据库访问技术对应的事务处理类都创建好了。

  • mybatis访问数据库—spring创建好的是DataSourceTransactionManager
  • hibernate访问数据库----spring创建的是HibernateTransactionManager

4)怎么使用:你需要告诉spring 你用是那种数据库的访问技术
在spring的配置文件中使用<bean>声明数据库访问技术对应的事务管理器实现类。 例如,你要使用mybatis访问数据库,你应该在xml配置文件中
<bean id=“xxx" class="…DataSourceTransactionManager">

2.spring需要知道业务方法需要什么样的事务,说明需要事务的类型。

说明业务方法需要的事务:
1)事务的隔离级别:有4个值。

  • DEFAULT:采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLE_READ; Oracle默认为 READ_COMMITTED。
  • READ_UNCOMMITTED:读未提交。未解决任何并发问题。
  • READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。
  • REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读
  • SERIALIZABLE:串行化。不存在并发问题。

2)事务的超时时间: 表示一个方法最长的执行时间,如果方法执行时超过了时间,事务就回滚。单位是秒, 整数值, 默认是 -1。

3)事务的传播行为 (重要): 控制方法是不是有事务的, 是什么样的事务的。有7个传播行为,表示你的业务方法调用时,事务在方法之间是如何使用的。

PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
PROPAGATION_SUPPORTS
以上三个需要掌握的

PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED

3.提交事务,回滚事务的时机
1)当你的业务方法执行成功,没有异常抛出。当方法执行完毕后,spring会通过事务管理器commit()自动提交事务。

2)当你的业务方法抛出运行时异常或ERROR, spring执行回滚,调用事务管理器的rollback()

运行时异常的定义: RuntimeException 和他的子类都是运行时异常, 例如NullPointException , NumberFormatException

3)当你的业务方法抛出非运行时异常, 主要是受查异常时,提交事务。这个异常提交是默认的,也可以定义为回滚。

受查异常:在你写代码的过程必须处理的异常。例如IOException, SQLException(默认异常)

总结spring的事务

  • 管理事务的是事务管理器和他的实现类
  • spring的事务是一个统一模型
    • 指定要使用的事务管理器实现类,使用<bean>
    • 指定哪些类,哪些方法需要加入事务的功能
    • 指定方法需要的隔离级别,传播行为,超时
  • 你需要告诉spring,项目中类的信息、方法的名称、方法的事务传播行为。

3.2.3 Spring 事务管理 API

Spring 的事务管理,主要用到两个事务相关的接口。

1.事务管理器接口(重点)
事务管理器是 PlatformTransactionManager 接口对象。其主要用于完成事务的提交、回滚,及获取事务的状态信息。

在这里插入图片描述
从官网https://docs.spring.io/spring-framework/docs/current/javadoc-api/的API可以看到

A. 常用的两个实现类
PlatformTransactionManager 接口有两个常用的实现类:

  • DataSourceTransactionManager:使用 JDBC 或 MyBatis 进行数据库操作时使用。
  • HibernateTransactionManager:使用 Hibernate 进行持久化数据时使用。

B 、 Spring 的回滚方式( 理解)
Spring 事务的默认回滚方式是:发生运行时异常和 error 时回滚,发生受查(编译)异常时提交。不过,对于受查异常,程序员也可以手工设置其回滚方式。

2.事务定义接口
事务定义接口TransactionDefinition中定义了事务描述相关的三类常量:事务隔离级别、事务传播行为、事务默认超时时限,及对它们的操作。

A 、 定义了五个事务隔离级别常量( 掌握)

  • DEFAULT:采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLE_READ; Oracle默认为 READ_COMMITTED。
  • READ_UNCOMMITTED:读未提交。未解决任何并发问题。
  • READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。
  • REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读
  • SERIALIZABLE:串行化。不存在并发问题。

B、定义了七个事务传播行为常量(掌握)
所谓事务传播行为是指,处于不同事务中的方法在相互调用时,执行期间事务的维护情况。如,A 事务中的方法 doSome()调用 B 事务中的方法 doOther(),在调用执行期间事务的维护情况,就称为事务传播行为。事务传播行为是加在方法上的。事务传播行为常量都是以 PROPAGATION_ 开头,形如 PROPAGATION_XXX。

前面介绍过,这里只介绍常用的三个:
a 、 PROPAGATION_REQUIRED
指定的方法必须在事务内执行。若当前存在事务,就加入到当前事务中;若当前没有事务,则创建一个新事务。这种传播行为是最常见的选择,也是 Spring 默认的事务传播行为。

如该传播行为加在 doOther()方法上。若 doSome()方法在调用 doOther()方法时就是在事务内运行的,则 doOther()方法的执行也加入到该事务内执行。若 doSome()方法在调用doOther()方法时没有在事务内执行,则 doOther()方法会创建一个事务,并在其中执行。

b、PROPAGATION_SUPPORTS
指定的方法支持当前事务,但若当前没有事务,也可以以非事务方式执行。例如:查询操作有事务没事务都可以。

c、PROPAGATION_REQUIRES_NEW
总是新建一个事务,若当前存在事务,就将当前事务挂起,直到新事务执行完毕。

C 、 定义了默认事务超时时限
常量 TIMEOUT_DEFAULT 定义了事务底层默认的超时时限,sql 语句的执行时长。

注意,事务的超时时限起作用的条件比较多,且超时的时间计算点较复杂。所以,该值一般就使用默认值即可。

3.3 案例分析

案例:购买商品 trans_sale 项目
需求:实现购买商品,模拟用户下订单,向订单表添加销售记录,从商品表减少库存。

准备工作:
1.创建maven项目
2.pom.xml文件添加相关依赖

3.3.1 创建数据库表

创建两个数据库表 sale , goods

sale:销售表
在这里插入图片描述
goods:
在这里插入图片描述

3.3.2 编写实体类

在这里插入图片描述
在这里插入图片描述

3.3.3 编写dao和mapper文件

saleDao
在这里插入图片描述
saleDao.xml
在这里插入图片描述
goodsDao:
在这里插入图片描述
goodsDao.xml:
在这里插入图片描述

3.3.4 编写service

service接口:
在这里插入图片描述

service实现类:
在这里插入图片描述

3.3.5 spring主配置文件

在这里插入图片描述
在spring的主配置文件中,我们需要配置数据库连接的相关信息,配置创建dao的相关属性以及声明service。因为在spring继承mybatis中,通过spring容器自动创建连接数据库,创建dao,创建service调用dao中方法的对象,需要在主配置文件中以<bean>的格式声明好,spring项目一启动,便可自动创建这些对象并由spring容器管理这些对象。开发人员只需在所需页面从容器中获取到dao对象,直接调用dao中的方便,便可完成操作。这样提高了代码编写的编写效率,同时也使得开发人员只需专注于业务开发,连接数据库等操作交由spring完成即可。

3.3.6 添加事务

在业务方法中添加事务属性:(有两种方式,下一节有介绍;这里以注解的方式介绍)
在这里插入图片描述
使用注解添加事务之前,需要先在主配置文件中添加事务的相关配置:
在这里插入图片描述

3.3.7 编写测试类

在这里插入图片描述

3.4 spring框架中提供的事务处理方案

3.4.1 中小项目适用于注解

spring框架用aop实现给业务方法增加事务的功能,使用@Transactional注解增加事务

@Transactional注解是spring框架自己的注解,放在public方法的上面,表示当前方法具有事务。可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等

1)使用@Transactional的步骤:
a.需要声明事务管理器对象
<bean id=“xx” class=“DataSourceTransactionManager”>

b.开启事务注解驱动, 告诉spring框架,使用的是注解的方式管理事务。spring使用aop机制,创建@Transactional所在的类代理对象,给方法加入事务的功能。

spring给业务方法加入事务:
 在你的业务方法执行之前,先开启事务,在业务方法之后提交或回滚事务,使用aop的环绕通知(环绕通知spring内部自己的实现的)
   
@Around("你要增加事务功能的业务方法名称")
Object myAround(){
     //开启事务,spring给你开启
	try{
	    buy(1001,10);
	  	spring的事务管理器.commit();
	 }catch(Exception e){
	    spring的事务管理器.rollback();
	 }

}

c.在你的方法的上面加入@Trancational

前面两步是在applicationContext.xml文件中添加的:
在这里插入图片描述
在要添加事务的public方法上加上注解:
在这里插入图片描述

2)@Transactional 的所有可选属性:

  • propagation:用于设置事务传播属性。该属性类型为 Propagation 枚举,默认值为Propagation.REQUIRED。
  • isolation:用于设置事务的隔离级别。该属性类型为 Isolation 枚举,默认值为Isolation.DEFAULT。
  • readOnly:用于设置该方法对数据库的操作是否是只读的。该属性为 boolean,默认值为 false。
  • timeout:用于设置本操作与数据库连接的超时时限。单位为秒,类型为 int,默认值为-1,即没有时限。
  • rollbackFor:指定需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
  • rollbackForClassName:指定需要回滚的异常类类名。类型为 String[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
  • noRollbackFor:指定不需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
  • noRollbackForClassName:指定不需要回滚的异常类类名。类型为 String[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。

注意:
@Transactional 若用在方法上,只能用于 public 方法上。对于其他非 public方法,如果加上了注解@Transactional,虽然 Spring 不会报错,但不会将指定事务引入到该方法中。因为 Spring 会忽略掉所有非 public 方法上的@Transaction 注解。若@Transaction 注解在类上,则表示该类上所有的方法均将在执行时引入事务

3.4.2 大型项目适用于使用aspectj框架

aspectj适合大型项目,有很多的类,方法,需要大量的配置事务,使用aspectj框架功能。spring配置文件中,声明类,方法需要的事务。这种方式使业务方法和事务配置完全分离。

实现步骤: 都是在xml配置文件中实现
1)使用aspectj框架,需要加入依赖

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.2.5.RELEASE</version>
</dependency>

该依赖可以到maven配置的相关网站查找需要的依赖信息:
https://mvnrepository.com/artifact/org.springframework/spring-aspects/5.3.5

2)声明事务管理器对象

   <bean id="xx" class="DataSourceTransactionManager">

在这里插入图片描述

  1. 声明方法需要的事务类型(配置方法的事务属性【隔离级别,传播行为,超时】)
    在这里插入图片描述

注意里面的rollback-for,如果发生的异常时指定的异常那么直接回滚,如果没有在rollback里面指定的异常,则判断是否是运行时异常,是则回滚。还有若像上图一样指定了多个<tx:method>,它是按顺序进行匹配的,也就是说最后一个name="*"是指除匹配完前面所有方法之外的其他方法,按照此事务属性去执行。

  1. 配置aop:在项目中,有可能很多的类需要添加事务功能,那么就可以用aop来指定哪些类要创建代理。

在这里插入图片描述

四、web项目中如何使用容器对象。

在 Web 项目中使用 Spring 框架,首先要解决在 web 层(这里指 Servlet)中获取到 Spring容器的问题。只要在 web 层获取到了 Spring 容器,便可从容器中获取到 Service 对象。

1.普通的javaSE项目有main方法,执行代码是执行main方法的,在main里面创建的容器对象 。
ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);

2.web项目是在tomcat服务器上运行的。 tomcat一起动,项目一直运行。多次请求会创建多次的spring的容器对象,很占用内存。实际上容器对象只需创建一次。也就是说对于web项目而言,每提交一次请求,就会创建一个新的 Spring 容器。但对于一个应用来说,只需要一个 Spring 容器即可。那么怎么在web项目中只创建一个spring容器呢?对于 Web 应用来说,ServletContext 对象是唯一的,一个 Web 应用,只有一个ServletContext 对象,该对象是在 Web 应用装载时初始化的。若将 Spring 容器的创建时机,放在 ServletContext 初始化时,就可以保证 Spring 容器的创建只会执行一次,也就保证了Spring 容器在整个应用中的唯一性。当 Spring 容器创建好后,在整个应用的生命周期过程中,Spring 容器应该是随时可以被访问的。即,Spring 容器应具有全局性。而放入 ServletContext 对象的属性,就具有应用的全局性。所以,将创建好的 Spring 容器,以属性的形式放入到 ServletContext 的空间中,就保证了 Spring 容器的全局性。这其实就是使用spring提供的监听器来创建容器对象的原理。

需求:
web项目中容器对象只需要创建一次,把容器对象放入到全局作用域ServletContext中。

怎么实现:
使用监听器,当全局作用域对象被创建时创建容器,并存入ServletContext。

监听器作用:
1)创建容器对象,执行 ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);
2)把容器对象放入到ServletContext, ServletContext.setAttribute(key,ctx)

4.1 案例:在web项目中使用spring,完成学生注册功能

实现步骤:
1.创建maven,web项目
2.加入相关依赖
  mybatis,spring,spring-mybatis,jdbc,jsp,servlet等依赖

3.添加实体类、dao接口、service接口及实现类和配置文件
4.创建一个jsp发起请求,有参数id,name ,email,age.
5.创建Servlet,接收请求参数, 调用 Service ,调用dao完成注册
6.创建一个jsp作为显示结果页面

使用 Spring 的监听器 ContextLoaderListener步骤:
1.添加maven依赖:
在这里插入图片描述

2.在web.xml文件中注册监听器并指定 Spring 配置文件的位置<context-param>
若 要 在 ServletContext 初 始 化 时 创 建 Spring 容 器 , 就 需 要 使 用 监 听 器 接 口ServletContextListener 对 ServletContext 进行监听,在 web.xml 中注册该监听器。
在这里插入图片描述
分析一下:
Spring 为该监听器接口定义了一个实现类 ContextLoaderListener,完成了两个很重要的
工作:创建容器对象,并将容器对象放入到了 ServletContext 的空间中。打开 ContextLoaderListener 的源码。看到一共四个方法,两个是构造方法,一个初始化
方法,一个销毁方法。
在这里插入图片描述
所以,在这四个方法中较重要的方法应该就是 contextInitialized(),context 初始化方法。

在这里插入图片描述
跟踪 initWebApplicationContext()方法,可以看到,在其中创建了容器对象。
在这里插入图片描述
并且,将创建好的容器对象放入到了 ServletContext 的空间中,key 为一个常量:
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
在这里插入图片描述

3.获取 Spring 容器对象
在 Servlet 中获取容器对象的常用方式有两种:直接从 ServletContext 中获取和通过 WebApplicationContextUtils 获取。

在controller中编写请求的代码(直接从 ServletContext 中获取创建好的容器对象):从对监听器 ContextLoaderListener 的源码分析可知,容器对象在 ServletContext 的中存放的 key 为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。所以,可以直接通过 ServletContext 的 getAttribute()方法,按照指定的 key 将容器对象获取到
在这里插入图片描述
也可以使用 WebApplicationContextUtils 获取容器对象:工具类 WebApplicationContextUtils 有一个方法专门用于从 ServletContext 中获取 Spring容器对象:getRequiredWebApplicationContext(ServletContext sc)
在这里插入图片描述

在这里插入图片描述
以上两种方式,无论使用哪种获取容器对象,刷新 success 页面后,可看到代码中使用
的 Spring 容器均为同一个对象,说明该容器对象只创建了一次。

注意:监听器可以自己创建,也可以使用框架中提供好的ContextLoaderListener

具体代码:
实体类:
在这里插入图片描述

接口和mapper文件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

service接口与实现类:
在这里插入图片描述

在这里插入图片描述
控制器:
在这里插入图片描述
web.xml
在这里插入图片描述
index.jsp
在这里插入图片描述
result.jsp
在这里插入图片描述
mybatis主配置文件
在这里插入图片描述
spring的主配置文件:
在这里插入图片描述
好了,今天的分享就到这~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值