?、Spring、SpringMVC、Mybatis框架整合
- 每次搭建 SSM 框架整合环境总是需要事先配置依赖,每次增添配置需要翻阅官网文档或者笔记进行查看,比较浪费时间,且有时候会引用错误。
- 本篇将开发中的常用依赖进行了整合,从依赖到配置文件的建立,包括数据源的抽离、日志文件的引入,MVC架构的搭建等进行了总结,coding 前整合好所有依赖,真正做到拿来即用。
- 这里将会配合简单小案例来进行测试,有每一步的详细图文教程,从开始的环境搭建、搭建成功测试 dao 层、service层、controller 层,以及测试增删改查、拦截器等来建立一个整合框架模板使用!
- IDEA 2021.1版本
- 参考视频教程:三更老师框架整合
?SSM框架之行🔥
1、SSM整合
1.1、步骤分析
我们先来分析下如何把Spring,SpringMVC,Mybatis整合到一起。
1.1.1、步骤
①Spring整合上Mybatis
? 通过Service层Dao层都注入Spring容器中
②引入配置SpringMVC
? 把Controller层注入SpringMVC容器中
③让web项目启动时自动读取Spring配置文件来创建Spring容器
? 可以使用ContextLoaderListener来实现Spring容器的创建。
1.1.2、常见疑惑
-
为什么要用两个容器? 因为Controller如果不放在MVC容器中会没有效果,无法处理请求。而Service如果不放在Spring容器中,声明式事务也无法使用。 -
SpringMVC容器中的Controller需要依赖Service,能从Spring容器中获取到所依赖的Service对象嘛? Spring容器相当于是父容器,MVC容器相当于是子容器。子容器除了可以使用自己容器中的对象外还可以使用父容器中的对象。 -
是什么时候让两个容器产生这种父子容器的关系的? 在ContextLoaderListener中,会在创建好容器后把容器存入servletContext域。这样在DispatcherServlet启动时,创建完SpringMVC容器后会从servletContext域中获取到Spring容器对象,设置为其父容器,这样子容器就能获取到父容器中的bean了。
1.2、准备工作
- 创建一个普通 maven 项目
- File -> Project Structure -> modules,添加 web 应用
- 将 web 移动到 main 目录下,并将其改名为 webapp,同时在 pom.xml 中添加打成 war 包的代码
- File -> Project Structure -> modules,查看路径是否爆红
- 不爆红则 OK
1.2.1、导入依赖
引入所有依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
1.2.2、数据库初始化
数据库初始化语句
CREATE DATABASE `mybatis_db` ;
USE `mybatis_db`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `user`(`id`,`username`,`age`,`address`) values
(1,'UZI',19,'上海'),
(2,'PDD',25,'上海');
1.3、相关配置
①整合Spring和Mybatis
- 在resources目录下创建Spring核心配置文件: applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.sangeng">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer">
<property name="basePackage" value="com.sangeng.dao"></property>
</bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
- 这里 mapper 扫描配置的是扫描 com.sangeng.dao 这个包,所以我们新建 dao 包
- 在resources目录下创建jdbc.properties 文件,内容如下:
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
- 在resources目录下创建mybatis-config.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>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<package name="com.sangeng.domain"></package>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
</configuration>
- 配置里面为 com.sangeng.domain 包配置了别名,所以我们在 com.sangeng 下建一个 domain 包
- 在resources目录下创建log4j.properties ,内容如下:
#将等级为DEBUG的日志信息输出到stdout,stdout定义在下面的代码
log4j.rootLogger=debug, stdout
#控制台输出的相关设置
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
#文件输出的相关设置
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=./log/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
②SpringMVC引入
- 在resources目录下创建spring-mvc.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.sangeng.controller"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
- 上方配置了 SpringMVC 扫描 controller包 ,所以我们要在 sangeng 下新建包 controller
- 最后修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
③Spring整合入web项目
让web项目启动的时候就能够创建Spring容器。可以使用Spring提供的监听器ContextLoaderListener,所以我们需要再 web.xml 中配置这个监听器,并且配置上Spring配置文件的路径。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这样我们的SSM整合配置层面就已经完成了,接下来我们编写测试
1.4、编写Controller,Service,Dao
我们来编写根据id查询用户的接口来进行测试
先有 Controller,请求过来被 Controller 里面的 Handler 所处理,在 Handler中 通过 Service 处理,Service 内部又会依赖 dao 去进行数据库的查询,dao 是使用 Mybatis 的写法
所以我们先写 Controller, 再写Service接口,实现Service接口中的方法,并且在Service实现类中注入dao,再去写dao,再去写对应的xml映射文件
1.4.1、编写实体类domain
- com.sangeng.domain.User.java 代码如下
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private Integer age;
private String address;
}
1.4.2、编写Service
- com.sangeng.service.UserService 接口 ,代码如下
public interface UserService {
User findById(Integer id);
}
- com.sangeng.service.impl.UserServiceImpl 实现类代码如下
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public User findById(Integer id) {
return userDao.findById(id);
}
}
@Service 注解使用在Service层类上用于实例化Bean,设置该类为spring管理的bean@Autowired 注解使用在字段上上用于根据类型依赖注入,为了从Spring容器中获得此对象
1.4.3、编写dao
- com.sangeng.dao.UserDao接口,代码如下
public interface UserDao {
User findById(Integer id);
}
- 针对接口生成对应的 mapper 映射文件,resources -> 右键 -> new Directory 生成对应的 mapper 目录
- 插件的存在可以帮我们一键生成 mapper.xml 映射文件,alt+回车 ,选择插件
- 这样我们只需要在生成的 mapper.xml 中写 sql 语句即可
- 所以 resources/com/sangeng/dao/UserDao.xml 代码如下:
<?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="com.sangeng.dao.UserDao">
<select id="findById" resultType="com.sangeng.domain.User">
select * from user where id = #{id}
</select>
</mapper>
1.4.4、1.4.4、编写Controller
需求:根据 id 去查询用户
- 所以 com.sangeng.controller.UserController ,代码如下:
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public User findById(@PathVariable Integer id){
User user = userService.findById(id);
return user;
}
}
-
加@Controller 注解使用在web层类上用于实例化Bean,设置该类为springMVC管理的bean -
加@ResponseBody 注解把返回值转换成 Json 格式放到响应体中。
@Controller + @ResponseBody = @RestController -
加@RequestMapping 注解是为了设置请求路径 -
加@Autowired 注解使用在字段上上用于根据类型依赖注入,为了从Spring容器中获得此对象 -
加@PathVariable 注解是获取请求路径的参数 -
最后我们在 pom.xml 中配置一下 tomcat插件
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
访问测试:
当然我们也可以不配置 tomcat 插件,而是将 tomcat 集成到 IDEA 中启动
2、案例
2.1、响应格式统一
我们要保证一个项目中所有接口返回的数据格式的统一。这样无论是前端还是移动端开发获取到我们的数据后都能更方便的进行统一处理。我们这里是将所有的数据格式统一为 json 格式。
所以我们定义以下结果封装类 ResponseResult,由于格式统一是公用的,所以我们可以在 com.sangeng 下创建一个公共 common 包,在包下创建结果封装类 ResponseResult
@JsonInclude(JsonInclude.Include.NON_NULL) 注解表示如果某个属性的值不为NULL,才会将其转化为Json格式
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> {
private Integer code;
private String msg;
private T data;
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
所以我们将之前的 controller 查询 id 为1返回的查询数据进行封装,修改代码如下 :
- 返回类型为我们封装的结果集 ResponseResult 类型
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public ResponseResult findById(@PathVariable("id") Integer id){
User user = userService.findById(id);
if(user==null){
return new ResponseResult(500,"没有该用户");
}
return new ResponseResult(200,"操作成功",user);
}
}
访问测试:
2.2、查询所有用户
- 在Controller层调用Service中的方法
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user")
public ResponseResult findAll(){
List<User> list = userService.findAll();
return new ResponseResult(200,"操作成功",list);
}
}
public interface UserService {
User findById(Integer id);
List<User> findAll();
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public List<User> findAll() {
return userDao.findAll();
}
}
public interface UserDao {
List<User> findAll();
}
- dao层利用插件生成 mapper.xml 文件如下
<?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="com.sangeng.dao.UserDao">
<select id="findAll" resultType="com.sangeng.domain.User">
select * from user
</select>
</mapper>
tomcat 插件启动展示:
IDEA 集成 tomcat 展示:
2.3、分页查询用户
分页查询的结果除了要包含查到的用户数据外还要有当前页数,每页条数,总记录数这些分页数据。
所以我们在 common 包下新建分页封装类 PageResult,代码如下:
public class PageResult<T> {
private Integer currentPage;
private Integer pageSize;
private Integer total;
private List<T> data;
public PageResult(Integer currentPage, Integer pageSize, Integer total, List<T> data) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.total = total;
this.data = data;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
- 编写Controller类,调用Service层的方法
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{pageSize}/{pageNum}")
public ResponseResult findByPage(@PathVariable("pageSize") Integer pageSize,@PathVariable("pageNum") Integer pageNum){
PageResult pageResult = userService.findByPage(pageSize,pageNum);
return new ResponseResult(200,"操作成功",pageResult);
}
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public PageResult findByPage(Integer pageSize, Integer pageNum) {
PageHelper.startPage(pageNum,pageSize);
List<User> list = userDao.findAll();
PageInfo pageInfo = new PageInfo(list);
PageResult pageResult = new PageResult(pageInfo.getPageNum(),pageInfo.getPageSize(), (int) pageInfo.getTotal(),list);
return pageResult;
}
}
2.4、插入用户
①编写 Controller 层,调用 service 层方法
- 我们是在请求体中传入Json格式的数据,
@RequestBody 注解可以获取请求体中的数据
@PostMapping("/user")
public ResponseResult insertUser(@RequestBody User user){
userService.insertUser(user);
return new ResponseResult(200,"操作成功");
}
②编写 Service 层,在 service 实现类中调用 dao 方法
void insertUser(User user);
public void insertUser(User user) {
userDao.insertUser(user);
}
③编写 Dao 层,使用插件生成 mapper.xml 映射文件
void insertUser(User user);
<insert id="insertUser">
insert into user values(null,#{username},#{age},#{address})
</insert>
④测试:我们向请求体当中传入Json数据
{"username":"三更草堂","age":15,"address":"请问"}
我们是把传入请求体的Json数据封装成User对象,在PostMan软件里演示,因为浏览器只方便演示GET请求
2.5、删除用户
①编写 Controller 层,调用 service 层方法
@DeleteMapping("/user/{id}")
public ResponseResult deleteUser(@PathVariable("id") Integer id){
userService.deleteUser(id);
return new ResponseResult(200,"操作成功");
}
②编写 Service 层,在 service 实现类中调用 dao 方法
void deleteUser(Integer id);
public void deleteUser(Integer id) {
userDao.deleteUser(id);
}
③编写 Dao 层,使用插件生成 mapper.xml 映射文件
void deleteUser(Integer id);
<delete id="deleteUser">
delete from user where id = #{id}
</delete>
在PostMan里面进行演示,删除id为3的用户
2.6、更新用户
①编写 Controller 层,调用 service 层方法
@PutMapping("/user")
public ResponseResult updateUser(@RequestBody User user){
userService.updateUser(user);
return new ResponseResult(200,"操作成功");
}
②编写 Service 层,在 service 实现类中调用 dao 方法
void updateUser(User user);
public void updateUser(User user) {
userDao.updateUser(user);
}
③编写 Dao 层,使用插件生成 mapper.xml 映射文件
void updateUser(User user);
<update id="updateUser">
update user set username = #{username},age = #{age},address = #{address} where id = #{id}
</update>
3、异常统一处理
我们可以使用@ControllerAdvice 实现对异常的统一处理。让异常出现时也能返回响应一个JSON。
我们在 com.sangeng 下创建包 exception,里面存放我们的异常统一处理类 SGControllerAdvice
代码如下:
@ControllerAdvice 注解设置当前类为异常处理器类@ExceptionHandler 注解设置指定异常的处理方式@ResponseBody 注解是将返回的Json数据放入响应体中
@ControllerAdvice
public class SGControllerAdvice {
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult handleException(Exception e){
return new ResponseResult(500,e.getMessage());
}
}
我们在Controller层查找用户方法中手动制造错误
@GetMapping("/user")
public ResponseResult findAll(){
System.out.println(1/0);
List<User> list = userService.findAll();
return new ResponseResult(200,"操作成功!",list);
}
4、拦截器
在 com.sangeng 下创建包 interceotor,在包里新建拦截器 SGHandlerInterceptor 类
创建拦截器的类
public class SGHandlerInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.sangeng.interceptor.SGHandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
测试
在IDEA控制台也输出了 preHandle、postHandle、afterCompletion
5、声明式事务
①编写 Controller 层,调用 service 层方法
@RequestMapping("/user/test")
public ResponseResult test(){
userService.test();
return new ResponseResult(200,"操作成功");
}
②编写 Service 层
void test();
- 实现类中实现该方法
- 已经做好了相应的配置,只要在service方法上加上注解即可
@Override
@Transactional
public void test() {
userDao.insertUser(new User(null,"test1",11,"cc"));
System.out.println(1/0);
userDao.insertUser(new User(null,"test2",12,"cc2"));
}
③测试
插入用户失败,因为有错误,会回滚事务。
6.AOP
注意,自己去使用AOP进行增强时,应该是对Service进行增强。不能对Controller进行增强,因为切面类会被放入父容器,而我们的Controller是在子容器中的。父容器不能访问子容器,子容器可以访问父容器
com.sangeng.aspect.SGAspect 代码如下:
@Aspect
@Component
public class SGAspect {
@Pointcut("execution(* com.sangeng.service..*.*(..))")
public void pt(){
}
@Before("pt()")
public void before(){
System.out.println("before");
}
}
启动测试发现AOP增强成功
- 如果需要对Controller进行增强,使用拦截器
- 如果需要对Service进行增强,使用AOP自己实现
|