Spring学习笔记
spring简介
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
目的:解决企业应用开发的复杂性
优点:
- spring是一个开源免费的容器(框架)
- spring是轻量级,非入侵式的框架
- Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。
- 支持事务的处理,支持对框架的整合。
总结一句话: Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
导入依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.4</version>
</dependency>
spring组成

扩展
-
springBoot
-
一个快速开发的脚手架。
-
基于springBoot可以快速的开发单个微服务。
-
约定大于配置。
-
-
springCloud
- springCloud是基于springBoot实现的。
IOC控制反转
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency lnjection,DI)
IOC创建对象
实体类
@Data
public class User(){
private String name;
}
user.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="jxnuss.my.pojo.Hello">
<property name="str" value="hello"></property>
</bean>
<bean id="userMysqlDao" class="jxnuss.my.dao.UserMysqlDaoImpl"></bean>
<bean id="userOracleDao" class="jxnuss.my.dao.UserOracleDaoImpl"></bean>
<bean id="userSqlServiceImpl" class="jxnuss.my.service.UserSqlServiceImpl">
<property name="userSqlDao" ref="userOracleDao"></property>
</bean>
</beans>
依赖注入
实体类
Address:
@Data
public class Address {
private String address;
}
Student:
@Data
public class Student {
private String name;
private Address address;
private String [] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private String wife;
private String work;
private Properties info;
}
list,map,set,array,null注入
<?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">
<bean name="address" class="com.my.pojo.Address">
<property name="address" value="北京西路"/>
</bean>
<bean name="student" class="com.my.pojo.Student">
<!--String-->
<property name="name" value="小明"/>
<!--Address对象-->
<property name="address" ref="address"/>
<!--Array-->
<property name="books">
<array>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!--List-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>打游戏</value>
<value>敲代码</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="身份证" value="36089951998062505445"/>
<entry key="银行卡号" value="264562654585565256"/>
</map>
</property>
<!--Set-->
<property name="games">
<set>
<value>LOL</value>
<value>王者荣耀</value>
<value>COC</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--""-->
<property name="work" value=""/>
<!--Properties-->
<property name="info">
<props>
<prop key="学号">201826701005</prop>
<prop key="学院">软件学院</prop>
<prop key="性别">男</prop>
</props>
</property>
</bean>
</beans>
测试
class StudentTest {
@Test
void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println("student = " + student);
}
}
运行结果:
student = Student(
name=小明,
address=Address(address=北京西路),
books=[西游记, 水浒传, 三国演义],
hobbies=[听歌, 打游戏, 敲代码],
card={身份证=36089951998062505445, 银行卡号=264562654585565256},
games=[LOL, 王者荣耀, COC],
wife=null,
work=,
info={学号=201826701005, 性别=男, 学院=软件学院})
Bean自动装配
在Spring 中,自动装配可以指定给每一个单独的 Bean,因此可以给一些Bean使用自动装配而其他的 Bean不使用自动装配。通过使用自动装配,开发人员可以减少指定属性的需要,从而节省一些属性设定的工作。使用Bean元素的autowire属性来指定 Bean定义的自动装配,共有5种模式,即 byName、byType、constructor、autodetect和 no。
byName模式
byName模式指的就是通过Bean 的属性名字进行自动装配。在Spring 的配置文档XML中,查找一个与将要装配的属性同样名字的 Bean。
在配置文档中,有一个id 为 HelloWorld 的 Bean被设置为通过 byName自动装配,HelloWorld.java包含一个date变量,Spring 就会查找一个叫做date 的 Bean定义,然后用它来设置date属性。使用byName模式的HelloWorld.java的示例代码如下:
@Data
public class HelloWorld{
private String msg;
private Date date;
}
<?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">
<bean id="HelloWorld" class="com.kuang.HelloWorld" autowire="byName">
<property name="msg" value="小明"/>
</bean>
<bean id="date" class="java.util.Date"/>
</beans>
byType模式
byType模式指的就是如果XML中正好有一个与属性类型一样的 Bean,就自动装配这个属性。如果有多于一个这样的Bean,就抛出一个异常,指出可能不能对那个Bean使用byType的自动装配。
@Data
public class HelloWorld{
private String msg;
private Date date;
}
<?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">
<bean id="HelloWorld" class="com.kuang.HelloWorld" autowire="byType">
<property name="msg" value="小明"/>
</bean>
<bean id="date11" class="java.util.Date"/>
</beans>
constructor模式
constructor模式指的就是根据构造函数的参数进行自动装配。在配置文档中,有一个id为HelloWorld 的 Bean 被设置为通过constructor自动装配,HelloWorld.java包含一个构造数方法,Spring就会根据构造函数的参数查找合适类型的Bean定义,然后用它来设置构造函数的参数的值。使用constructor模式的HelloWorld.java的示例代码如下:
@Data
public class HelloWorld{
private String msg;
private Date date;
public HelloWorld(Date date){
this.date=date;
}
}
<?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">
<bean id="HelloWorld" class="com.kuang.HelloWorld" autowire="constructor">
<property name="msg" value="小明"/>
</bean>
<bean id="date11" class="java.util.Date"/>
</beans>
autodetect模式
autodetect模式指的就是通过对 Bean检查类的内部来选择constructor或 byType。如果先找到constructor就用constructor;如果没有constructor,而找到 byType,就用byType。
no模式
no模式指的就是不使用自动装配。通过上面几节可以了解到,Bean 的引用必须通过ref元素定义。这是默认的配置,在很多企业级的应用环境中不鼓励使用自动装配模式,因为它对于Bean之间的参考依赖关系不清晰。
@Data
public class HelloWorld{
private String msg;
private Date date;
}
<?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">
<bean id="HelloWorld" class="com.kuang.HelloWorld" autowire="constructor">
<property name="msg" value="小明"/>
<property name="date" ref="date11"/>
</bean>
<bean id="date11" class="java.util.Date"/>
</beans>
注解实现自动装配
导入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">
<!-- 开启注解支持 -->
<context:annotation-config/>
</beans>
@Autowired
@Autowired默认按照类型匹配注入bean,如果有多个类型相同的,再通过名称查找。
@Autowired搭配@Qualifier(“实现类名称”)表明注入的是哪一个实现类的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" 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"> <!-- 开启注解支持 --> <context:annotation-config/> <bean id="cat" class="com.xcz.pojo.Cat"/> <bean id="dog" class="com.xcz.pojo.Dog"/> <bean id="people" class="com.xcz.pojo.People"/> </beans> -
实体类
@Data public class People { private String name; @Autowired private Cat cat; @Autowired private Dog dog; public void shout(){ cat.shout(); dog.shout(); } } public class Dog { public void shout(){ System.out.println("Dog...."); } } public class Cat { public void shout(){ System.out.println("Cat...."); } } -
测试
public class PeopleTest extends TestCase { public void testShout() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = context.getBean("people",People.class); people.shout(); } 结果: Cat.... Dog....
@Qualifier
Qualifier ,读音:[ˈkwɒlɪfaɪə(r)] 的意思是合格者,通过这个标示,表明了哪个类才是我们所需要的;
<bean id="cat" class="com.xcz.pojo.Cat"/>
<bean id="dog" class="com.xcz.pojo.Dog"/>
<bean id="dog11" class="com.xcz.pojo.Dog"/>
<bean id="people" class="com.xcz.pojo.People"/>
public class People {
private String name;
@Autowired
private Cat cat;
@Autowired
@Qualifier(value = "dog11")
private Dog dog;
public void shout(){
cat.shout();
dog.shout();
}
}
@Resource
@Resource默认按照名称匹配注入bean,而且可以使用name作为属性来确定实际注入的bean,如果按照名称无法找到就byType,byType有多个的话也会失败。
<bean id="dog11" class="com.xcz.pojo.Dog"/>
<bean id="dog22" class="com.xcz.pojo.Dog"/>
@Resource(name = "dog22")
private Dog dog;
有多个类型相同的bean时,@Autowired配合 @Qualifier(value = "...")来准确找到bean, @Resource(name = "...")来找bean
Spring注解开发
使用注解开发,要开启包扫描器
<?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"> <!--指定要扫描的包,这个包下的注解就会生效--> <context:component-scan base-package="com.xcz"/> </beans>
@Component
把普通pojo实例化到spring容器中,相当于配置文件中的
<bean id="" class=""/>
@Component衍生注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层
- dao 【@Repository】
- service【@Service】
- controller【@Controller】
这4个注解意思一样,都是把类注册到spring容器中。
事务处理
什么是事务
事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
典型场景:银行转账
lucy转账 100元 给 marye
lucy 少100,mary多100
事务的4大特性
(1)原子性
(2) 一致性
(3)隔离性
(4)持久性
spring整合Mybatis
第一步:创建测试工程
第一步,首先在 IDEA 中新建一个名为【MybatisAndSpring】的 WebProject 工程:

然后在【src】中创建 4 个空包:
- cn.wmyskxz.dao(放置 DAO 数据交互层处理类)
- cn.wmyskxz.mapper(放置 Mapper 代理接口)
- cn.wmyskxz.pojo(放置 Java 实体类)
- cn.wmyskxz.test(放置测试类)
接着新建源文件夹【config】,用于放置各种资源配置文件:
- 在【config / mybatis】下创建一个空的名为 “SqlMapConfig.xml” 的 MyBatis 全局配置文件
- 在【config / spring】下创建一个空的名为 “applicationContext.xml” 的 Spring 资源配置文件
- 在【config / sqlmap】下创建一个空的名为 “UserMapper.xml” 的 Mapper 映射文件。
- 在【config】下创建两个 properties 属性文件,分别为 “db.properties” 和 “log4j.properties”,用于数据库连接和日志系统参数设置。
再在【web】文件夹下新建一个【WEB-INF】默认安全文件夹,并在其下创建一个【classes】和【lib】,并将项目的输出位置,改在【classes】下:

工程的完整初始结构如下:

第二步:引入依赖 jar 包
第二步,就是要准备项目的依赖 jar 包:
- MyBatis 的包(MyBatis 3.4.6)
- Spring 的 jar 包(Spring 4.3.15)
- MyBatis 与 Spring 的整合 jar 包(mybatis-spring 1.3.2)
- mysql-connector-java-5.1.21.jar
- junit-4.12.jar

在【WEB-INF】文件夹下的【lib】文件夹中放置上面列举的 jar 包,然后添加依赖。
第三步:编写 Spring 配置文件
第三步,编写 Spring 的配置文件:
- 加载数据库连接文件 “db.properties” 中的数据,建立数据源
- 配置 sqlSessionFactory 会话工厂对象
<?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">
<!-- 加载配置文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载 MyBatis 的配置文件 -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"/>
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- SqlSessionTemplate -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 构造器注入 -->
<constructor-arg index="0" ref="sqlSessionFactory"/>
<!-- 也可以这样写:<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/> -->
</bean>
</beans>
- 头部的信息就是声明 xml 文档配置标签的规则的限制与规范。
- “context:property-placeholder” 配置是用于读取工程中的静态属性文件,然后在其他配置中使用时,就可以采用 “${属性名}” 的方式获取该属性文件中的配置参数值。
- 配置了一个名为 “dataSrouce” 的 bean 的信息,实际上是连接数据库的数据源。
- 设置 sqlSessionFactory 的 bean 实现类为 MyBatis 与 Spring 整合 jar 包中的 SqlSessionFactoryBean 类,在其中只需要注入两个参数:一个是 MyBatis 的全局配置文件,一个是上面配置的数据源 bean
第四步:编写 MyBatis 配置文件
第四步,在【mybatis】包下编写 MyBatis 的全局配置文件 SqlMapConfig.xml :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- settings -->
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载(即按需加载) -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 打开全局缓存开关(二级缓存)默认值就是 true -->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 别名定义 -->
<typeAliases>
<package name="cn.wmyskxz.pojo"/>
</typeAliases>
<!-- 加载映射文件 -->
<mappers>
<!-- 通过 resource 方法一次加载一个映射文件 -->
<mapper resource="sqlmap/UserMapper.xml"/>
<!-- 批量加载mapper -->
<package name="cn.wmyskxz.mapper"/>
</mappers>
</configuration>
在该配置文件中:
- 通过 settings 配置了一些延迟加载和缓存的开关信息
- 在 typeAliases 中设置了一个 package 的别名扫描路径,在该路径下的 Java 实体类都可以拥有一个别名(即首字母小写的类名)
- 在 mappers 配置中,使用 mapper 标签配置了即将要加载的 Mapper 映射文件的资源路径,当然也可以使用 package 标签,配置 mapper 代理接口所在的包名,以批量加载 mapper 代理对象。
- 注意: 有了 Spring 托管数据源,在 MyBatis 配置文件中仅仅需要关注性能化配置。
第五步:编写 Mapper 以及其他配置文件
第五步,编写 Mapper 映射文件,这里依然定义 Mapper 映射文件的名字为 “UserMapper.xml” (与 SqlMapConfig.xml 中配置一致),为了测试效果,只配置了一个查询类 SQL 映射:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
<select id="findUserById" parameterType="_int" resultType="user">
SELECT * FROM USER WHERE id = #{id}
</select>
</mapper>
在该配置中,输出参数的映射为 “user” ,这是因为之前在 SqlMapConfig.xml 中配置了 “cn.wmyskxz.pojo” 包下的实体类使用别名(即首字母小写的类名),所以这里只需在 “cn.wmyskxz.pojo” 包下,创建 “finduserById” 对应的 Java 实体类 User:
package cn.wmyskxz.pojo;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String username;
/* getter and setter */
}
- 实现 Serializable 接口是为之后使用 Mapper 动态代理做准备,这里没有使用动态代理。
在数据库资源 “db.properties” 中配置了数据库的连接信息,以 “key=value” 的形式配置,String 正是使用 “${}” 获取其中 key 对应的 value 配置的:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
另外日志配置和之前的配置一样,我就直接黏贴了:
# Global logging configuration
# 在开发环境下日志级别要设置成 DEBUG ,生产环境设为 INFO 或 ERROR
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
第六步:编写 Service 测试类
在 “cn.wmyskxz.test” 包下创建【UserServiceTest】测试类:
package cn.wmyskxz.test;
import cn.wmyskxz.dao.UserDAO;
import cn.wmyskxz.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceTest {
private ApplicationContext applicationContext;
// 在执行测试方法之前首先获取 Spring 配置文件对象
// 注解@Before在执行本类所有测试方法之前先调用这个方法
@Before
public void setup() throws Exception {
applicationContext = new
ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() throws Exception {
// 通过配置资源对象获取 userDAO 对象
SqlSessionTemplate SqlSession = (SqlSessionTemplate) applicationContext.getBean("sqlSession");
// 调用 UserMapper 的方法
UserMapper userMapper = SqlSession.getMapper(UserMapper.class);
User user userMapper.findUserById(1);
// 输出用户信息
System.out.println(user.getId() + ":" + user.getUsername());
}
}
运行测试方法,输出结果如下:

动态代理 + 注解实现
上面的实例程序并没有使用 Mapper 动态代理和注解来完成,下面我们就来试试如何用动态代理和注解:
第一步:编写 UserQueryMapper
在【mapper】下新建一个【UserQueryMapper】代理接口,并使用注解:
package cn.wmyskxz.mapper;
import cn.wmyskxz.pojo.User;
import org.apache.ibatis.annotations.Select;
public interface UserQueryMapper {
@Select("SELECT * FROM USER WHERE id = #{id}")
public User findUserById(int id) throws Exception;
}
- 注意: 在默认情况下,该 bean 的名字为 userQueryMapper(即首字母小写)
现在有了代理类,我们需要通知 Spring 在这里来扫描到该类,Mapper 扫描配置对象需要用专门的扫描器:
<!-- Mapper 扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描 cn.wmyskxz.mapper 包下的组件 -->
<property name="basePackage" value="cn.wmyskxz.mapper"/>
</bean>
第二步:编写测试类
这一次我们获取的不再是 userDAO 对象,而是定义的 Mapper 代理对象 userQueryMapper:
package cn.wmyskxz.test;
import cn.wmyskxz.mapper.UserQueryMapper;
import cn.wmyskxz.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceTest {
private ApplicationContext applicationContext;
// 在执行测试方法之前首先获取 Spring 配置文件对象
// 注解@Before在执行本类所有测试方法之前先调用这个方法
@Before
public void setup() throws Exception {
applicationContext = new
ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() throws Exception {
// 通过配置资源对象获取 userDAO 对象
UserQueryMapper userQueryMapper = (UserQueryMapper) applicationContext.getBean("userQueryMapper");
// 调用 UserDAO 的方法
User user = userQueryMapper.findUserById(1);
// 输出用户信息
System.out.println(user.getId() + ":" + user.getUsername());
}
}
运行测试方法,得到正确结果:

可以看到,查询结果和之前非 Mapper 代理的查询结果一样。
- 原理: 在 applicationContext.xml 配置文件中配置的 mapper 批量扫描器类,会从 mapper 包中扫描出 Mapper 接口,自动创建代理对象并且在 Spring 容器中注入。自动扫描出来的 Mapper 的 bean 的 id 为 mapper 类名(首字母小写),所以这里获取的就是名为 “userQueryMapper” 的 mapper 代理对象。

浙公网安备 33010602011771号