一、开发环境搭建
注意:⚠️ 在搭建环境的时候,稍微注意下版本对应关系,下面是JDK和Tomcat版本对应关系
本教程环境如下所示:
- JDK版本:8\11
- 开发工具:STS 3.9
- 服务器:Tomcat 7.0.52
- Spring:5.2.3
- Lombok:1.18.28
准备好开发工具后,我们先打开STS编辑器,创建一个Spring项目:
创建好之后的项目骨架大概如图所示:
二、整合Spring框架
既然我们包都已经导进去了,我们接下来先整合Spring框架。
- 导入依赖包
- 创建Spring Ioc容器配置文件
打开所有命名空间,省的后面慢慢加
生成的配置文件如下:
<?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:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 包扫描 -->
<context:component-scan base-package="io.spring.*.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
- 编写测试实体
@Component
public class Student {
public void play() {
System.out.println("play computer games!");
}
}
- 编写测试类
public class TestApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:config/spring-config.xml");
Student student = context.getBean(Student.class);
student.play();// 打印输出:play computer games!
}
}
然后你会发现,这种测试类的加载Spring IoC容器,是通过ClassPathXmlApplicationContext
去手动加载,但是我们项目是Web应用,应该是跟随应用容器启动的时候去自己加载。
- 删除测试类,修改
web.xml
的配置
注:🔍 按住
Alt+/
快捷键,会出现ContextLoaderListener
提示,选择它,就会生成代码。
然后web.xml
会多出以下配置(修改下spring-config.xml
的路径)
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-config.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
但是到现在为止,我们还是没法进行测试,我们需要把Spring MVC
集成进来。
- 新建
springmvc-config.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:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- MVC注解支持 -->
<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="io.spring.*.action">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 视图解析器 -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 后缀:.jsp/.html都可以 -->
<property name="suffix" value=".jsp"></property>
<!-- 前缀:pages与WEB-INF同级 -->
<property name="prefix" value="/pages/"></property>
</bean>
</beans>
- 修改
web.xml
配置,配置视图映射
🔍 按住
Alt+/
快捷键,会出现DispatcherServlet
提示,选择它,就会生成代码。
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>*.asp</url-pattern>
</servlet-mapping>
编写测试接口
package io.spring.test.action;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import io.spring.test.pojo.Student;
@Controller
public class TestAction {
@Autowired
private Student student;
/**
* 这种直接解析视图
* @return
*/
@RequestMapping("test1.asp")
public String test1() {
return "test/test";
}
/**
* 直接返回数据
* @return
*/
@RequestMapping("test2.asp")
public @ResponseBody String test2() {
return student.play();
}
}
测试实体类
package io.spring.test.pojo;
import org.springframework.stereotype.Component;
@Component
public class Student {
public String play() {
return "play computer games!";
}
}
JSP测试页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
Hello Spring、Spring MVC!
</body>
</html>
浏览器分别访问http://localhost:8080/ssm-demo/test1.asp
、http://localhost:8080/ssm-demo/test2.asp
,结果如下
这就意味着我们Spring框架和MVC框架已经成功集成。
三、整合MyBatis框架
在开始之前,我们还是需要主义的就是,版本问题,下面我们来看下版本之间的兼容性说明。
MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
---|---|---|---|---|
3.0 | 3.5+ | 6.0+ | 5.0+ | Java 17+ |
2.1 | 3.5+ | 5.x | 4.x | Java 8+ |
2.0 | 3.5+ | 5.x | 4.x | Java 8+ |
1.3 | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
所以我们应该选择3.5.x
版本的MyBatis,以及2.1版本的MyBatis-spring中间件。
- 下载依赖包
- 项目骨架
- 创建配置文件
1、mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 如果不集成mybatis-spring,就需要通过XML构建 SqlSessionFactory -->
<!-- 使用Spring的时候,environments 就是废弃的配置,不使用 -->
<!-- <properties resource="config/mysql.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="{user}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments> -->
<!-- 设置别名 -->
<!-- <typeAliases>
<package name="io.spring.test.pojo"/>
</typeAliases> -->
<!-- <typeAliases>
<typeAlias type="io.spring.test.pojo.Student" alias="student"/>
</typeAliases> -->
<mappers>
<mapper resource="/config/mybatis-studentmapper.xml" />
</mappers>
</configuration>
2、mybatis-studentmapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.spring.test.mapper.StudentMapper">
<!-- query all students -->
<select id="queryAll" resultType="student">
select * from student
</select>
</mapper>
3、mysql.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/spring_test
user=root
password=NJI(mko0
4、spring-config.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:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 包扫描 -->
<context:component-scan base-package="io.spring.*.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置文件加载 -->
<context:property-placeholder location="classpath:config/mysql.properties"/>
<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="url" value="${url}"></property>
<property name="driverClassName" value="${driver}"></property>
</bean>
<!-- 要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:/config/mybatis-config.xml"></property>
<property name="dataSource" ref="dataSource"></property>
<!-- alias name -->
<property name="typeAliasesPackage" value="io.spring.*.pojo"></property>
</bean>
<!-- Mapper代理 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="io.spring.*.mapper"></property>
</bean>
</beans>
5、springmvc-config.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:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- MVC注解支持 -->
<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="io.spring.*.action">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 视图解析器 -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 后缀:.jsp/.html都可以 -->
<property name="suffix" value=".jsp"></property>
<!-- 前缀 -->
<property name="prefix" value="/pages/"></property>
</bean>
</beans>
6、TestAction.java
package io.spring.test.action;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import io.spring.test.mapper.StudentMapper;
import io.spring.test.pojo.Student;
import io.spring.test.service.StudentService;
@Controller
public class TestAction {
@Autowired
private StudentService studentService;
@Autowired
private Student student;
@RequestMapping("test1.asp")
public String test1() {
return "test/test";
}
@RequestMapping("test2.asp")
public @ResponseBody String test2() {
return student.toString();
}
@RequestMapping("queryAll.asp")
public @ResponseBody List<Student> queryAll() {
studentService.queryAll().forEach(System.out::println);
return null;
}
}
7、StudentMapper.java
package io.spring.test.mapper;
import java.util.List;
import org.springframework.stereotype.Repository;
import io.spring.test.pojo.Student;
@Repository
public interface StudentMapper {
List<Student> queryAll();
}
8、Stduent.java
package io.spring.test.pojo;
import java.math.BigInteger;
import org.springframework.stereotype.Component;
@Component
public class Student {
private BigInteger id;
private String name;
public Student() {
super();
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
9、StudentService.java
package io.spring.test.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import io.spring.test.mapper.StudentMapper;
import io.spring.test.pojo.Student;
import io.spring.test.service.StudentService;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> queryAll() {
return studentMapper.queryAll();
}
}
10、StudentService.java
package io.spring.test.service;
import java.util.List;
import org.springframework.stereotype.Service;
import io.spring.test.pojo.Student;
@Service
public interface StudentService {
List<Student> queryAll();
}
11、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ssm-demo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-config.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>*.asp</url-pattern>
</servlet-mapping>
</web-app>
到这里,浏览器访问接口localhost:8080/ssm-demo/queryAll.asp
,控制台输出:
Student [id=1, name=caixibei]
Student [id=2, name=zhangjunhao]
Student [id=3, name=renzhenyu]
Student [id=15, name=caicai]
Student [id=16, name=hh]
Student [id=17, name=caicai]
Student [id=18, name=hh]
Student [id=19, name=caicai]
Student [id=20, name=hh]
Student [id=21, name=caicai]
Student [id=22, name=hh]
Student [id=23, name=caicai]
Student [id=24, name=hh]
四、配置说明
整合了这么久,我们只是一股脑的整合完,但是没有过多的去解释为什么这么做?下面我们简单的说明下。
相信你也看到,我写的这两个配置,也许你不知道为什么我要这样弄,难道仅仅只是因为是为了分开两个概念?不是,只是很有可能会遇到一种情况导致Spring事务失效!
客观请看,具体如下所示:
Spring事务: context:exclude-filter
。如果带上事务,那么用annotation方式的事务注解和bean配置,事务会失效,要将service bean配置到xml文件中才行。
🔔 这个问题很经典了!!! 在主容器中(applicationContext.xml),将Controller的注解排除掉:
<context:component-scan base-package="com">
<context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" />
</context:component-scan>
而在springMVC配置文件中将Service注解给去掉:
<context:component-scan base-package="com">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
因为spring的context是父子容器,所以会产生冲突,Controller会先进行扫描装配,而此时的Service还没有进行事务的增强处理,得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力) ,最后才是applicationContext.xml中的扫描配置进行事务处理。
这个配置,你也会发现通过mybatis-config.xml
再通过**mapper.xml
去代理我们的接口,着实麻烦。
我们也可以修改成:
这样一来,我们连mybatis-config.xml
文件都可以删除了!
这个是最关键的!我把它删除后,看下会发生什么?
为什么呢?
回过头来看看我们的StudentMapper
是个什么玩意儿
他是接口啊!肯定不能实例化啊?所以我们要做的就是让Mapper通过动态代理,生成代理类之后,再去实例化。
🔍 思考:既然接口不能注入,那抽象类呢?
答案是:也不能!因为Java不支持多继承,而Mybatis在给类做动态代理(JDK动态代理)的时候,是需要继承$Proxy类的。
🔍 思考:JDK能给类动态代理吗?
答案是:不能。 JDK动态代理只支持接口。