【Spring MVC学习笔记 四】Spring-SpringMVC-MyBatis框架整合

学习完了Spring、SpringMVC、MyBatis的大部分相关内容后,我们来整合一个SSM框架来强化这段时间的学习认知,除了主线任务,还涉及到事务实现、日志AOP实现、MyBatis日志实现、并且在主线任务中创建各个层的实体类,当然因为比较简单,实体类的属性其实都一样,但是为了项目的完整性,一个都不能少。最后我们知道框架都有注解+配置的实现方式,我们会在适合的模块用适合的方式,例如MyBatis就使用配置好一些,Spring的AOP日志实现使用配置好一些,其它的都是使用注解好些,也就是我们会使用注解+配置的混合开发模式

创建一个新项目

首先我们创建一个新的项目,名称是ssm-frame
在这里插入图片描述

1 项目结构规划

项目整体结构如下:
在这里插入图片描述

2 Maven坐标导入

我们统一导入所有需要的Maven坐标,每个需要的模块我会用注释标识:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>ssm-frame</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>ssm-frame</name>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.7.1</junit.version>
    </properties>

    <dependencies>
        <!-- Spring相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
        <!-- Mybatis相关 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- Mybatis-Spring相关 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.9</version>
        </dependency>

        <!--Spring MVC框架依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>

        <!--JSP-Servlet相关依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <!-- 单元测试相关 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- 日志相关 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.32</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

3 数据库关系表创建

创建person表,并插入几条数据:
在这里插入图片描述

MyBatis框架实现

接下来我们实现下MyBatis框架,按照如下的步骤实现:

1 domain实体类创建(PO)

首先我们需要创建一个持久化实体

Person

package com.example.ssm_frame.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/*
 * person表对应对象
 * */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private int id;
    private String username;
    private String password;
    private int age;
    private int phone;
    private String email;
    private String hobby;
}

2 PersonDao接口创建

然后创建两个接口方法,用来操作person表数据

PersonDao

package com.example.ssm_frame.dao;


import com.example.ssm_frame.model.Person;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface PersonDao {
    List<Person> getPersonList();
    int addPerson(Person person);
}

3 personMapper.xml映射文件编写

绑定personMapper.xml文件如下:

personMapper.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">

<!--namespace=绑定一个指定的Dao/Mapper接口-->
<mapper namespace="com.example.ssm_frame.dao.PersonDao">
    <select id="getPersonList" resultType="com.example.ssm_frame.model.Person">
        select * from person
    </select>
    <insert id="addPerson" parameterType="com.example.ssm_frame.model.Person" >
        insert into person (id,username,password,age,phone,email,hobby) values (#{id},#{username},#{password},#{age},#{phone},#{email},#{hobby})
    </insert>
</mapper>

4 db.properties及日志配置编写

我们需要给数据库绑定访问属性:

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=root

然后我们需要配置相关日志:

log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
# 设置日志输出级别以及输出目的地,可以设置多个输出目的地,开发环境下,日志级别要设置成DEBUG或者ERROR
# 前面写日志级别,逗号后面写输出目的地
# log4j.rootLogger = [level],appenderName1,appenderName2,…
log4j.rootLogger=Debug,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 输出到控制台
log4j.appender.console.Target = System.out
# 指定控制台输出日志级别
log4j.appender.console.Threshold=DEBUG
# 默认值是 true, 表示是否立即输出
log4j.appender.console.ImmediateFlush = true
# 设置编码方式
log4j.appender.console.Encoding = UTF-8
# 日志输出布局
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 如果日志输出布局为PatternLayout 自定义级别,需要使用ConversionPattern指定输出格式
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
# 指定输出文件路径
log4j.appender.file.File=./log/tml.log
# 指定单个日志文件最大值
log4j.appender.file.MaxFileSize=10mb
# 指定输出日志级别
log4j.appender.file.Threshold=DEBUG
# 默认值是 true, 表示是否立即输出
log4j.appender.file.ImmediateFlush = true
# 设置编码方式
log4j.appender.file.Encoding = UTF-8
# 日志输出布局
log4j.appender.file.layout=org.apache.log4j.PatternLayout
# 如果日志输出布局为PatternLayout 自定义级别,需要使用ConversionPattern指定输出格式
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sq1.PreparedStatement=DEBUG

5 mybatis-config.xml核心配置编写

我们需要配置核心的mybatis配置文件:

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核心配置文件-->
<configuration>
    <!--导入properties文件-->
    <properties resource="properties/db.properties"/>
    <settings>
        <setting name="logImpl" value="log4j"/>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <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="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mappers/personMapper.xml"/>
    </mappers>

</configuration>


6 spring-dao.xml整合配置编写

然后我们需要将MyBatis的相关配置整合到Spring中,所以SqlSession的创建及Mapper对象的创建都托管给了Spring:

spring-dao.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"
       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 ">

    <!-- 扫描dao相关的bean,Mapper对象自动扫描注入Spring-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描Dao接口包,扫描后依据接口自动创建Mapper对象 -->
        <property name="basePackage" value="com.example.ssm_frame.dao"/>
    </bean>

    <!--配置SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!-- 加载数据库配置信息 -->
    <context:property-placeholder location="classpath:properties/db.properties" system-properties-mode="NEVER"/>
    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>
    
</beans>


Spring框架实现

接下来我们实现下Spring框架,按照如下步骤。

1 数据传输类创建(DTO)

理论上DTO和PO不同,需要做转换,但是这里我们项目比较简单,所以还用之前的Person

2 PersonService接口创建

然后我们需要创建PersonService。

PersonService

package com.example.ssm_frame.service;


import com.example.ssm_frame.model.Person;

import java.util.List;

public interface PersonService {
    List<Person> getPersonList();
    int addAndSendPerson(Person person);
}

3 PersonServiceImpl实现类创建

依据PersonService实现PersonServiceImpl,这里我们使用自动装配调用Dao层自动生成的Mapper对象。

PersonServiceImpl

package com.example.ssm_frame.serviceImpl;


import com.example.ssm_frame.dao.PersonDao;
import com.example.ssm_frame.model.Person;
import com.example.ssm_frame.service.PersonService;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class PersonServiceImpl implements PersonService {

    @Resource
    private PersonDao personDao;

    @Override
    public List<Person> getPersonList() {
        List<Person> personList=personDao.getPersonList();
        for (Person person : personList) {
            System.out.println(person);
        }
        return personList;
    }

    @Override
    @Transactional
    public int addAndSendPerson(Person person) {
        int result=personDao.addPerson(person);
        this.sendMessage(person);
        return result;
    }

    public void sendMessage(Person person){
        System.out.println("人员新增到下游系统失败"+person);
        throw new RuntimeException();

    }
}

4 日志监控AOP类创建

我们需要用AOP实现方法前后的记录:

LogAop

package com.example.ssm_frame.aop;

import java.time.LocalDateTime;

/**
 * * @Name LogProxy
 * * @Description
 * * @author tianmaolin
 * * @Data 2021/8/24
 */
public class LogAop {


    public void beforeLog()  {
        System.out.println("日志记录开始"+ LocalDateTime.now());
    }


    public void afterLog()  {
        System.out.println("日志记录结束"+ LocalDateTime.now().plusMinutes(5));
    }
}

5 applicationContext.xml核心配置编写

我们需要配置核心的启动配置文件,当然现在为空,最后我们再整合

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

 
</beans>


6 spring-service.xml整合配置编写

然后我们配置下spring-service.xml来实现事务管理和日志管理

spring-service.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:tx="http://www.springframework.org/schema/tx" 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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

     <!-- 扫描service相关的bean,自动注入Spring-注解配置开启,该配置项其实也包含了自动注入功能,
     因此当使用<context:component-scan/>后,即可将<context:annotation-config/>省去 -->
    <context:component-scan base-package="com.example.ssm_frame.serviceImpl" />

    <!-- 配置事务管理器,开启事务的注解驱动-->
    <tx:annotation-driven />
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource" />
    </bean>
    <!-- 配置日志管理器-->
    <bean id="logAop" class="com.example.ssm_frame.aop.LogAop"></bean>
    <!--aop的配置-日志记录-->
    <aop:config proxy-target-class="true">
        <aop:aspect ref="logAop">
            <!--切点-->
            <aop:pointcut id="logPointCut" expression="execution(* com.example.ssm_frame.service..*.*(..))"/>
            <!--切点-通知-->
            <aop:before pointcut-ref="logPointCut" method="beforeLog"/>
            <aop:after pointcut-ref="logPointCut" method="afterLog"/>
        </aop:aspect>
    </aop:config>
</beans>

SpringMVC框架实现

接下来我们开始配置SpringMVC框架以及整合配置文件。

1 视图对象类创建(VO)

理论上VO和PO不同,需要做转换,但是这里我们项目比较简单,所以还用之前的Person

2 控制器PersonController类创建

我们来配置中心控制器,并自动装配Service层的实现,调用方法获取结果传输到JSP页面。

PersonController

package com.example.ssm_frame.controller;

import com.example.ssm_frame.model.Person;
import com.example.ssm_frame.serviceImpl.PersonServiceImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;

import java.util.List;

@Controller
@RequestMapping("/person")
public class PersonController {
    @Resource
    private PersonServiceImpl personServiceImpl;
    @RequestMapping("getPersonList")
    public String requestDispatch(@RequestParam("username") String username, ModelMap modelMap) {
        if(username.equals("root")){
           List<Person> personList=personServiceImpl.getPersonList();
            modelMap.addAttribute("personList", personList);
        }
        return "list";
    }
}

注意SpringMVC默认的作用域时一次request,无论是Model还是ModelMap,放置的上下文作用域都是一次request。

3 视图页list.jsp创建

然后我们编写写列表信息:

list.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page  pageEncoding="UTF-8" %>

<html>
<head>
    <title>人员列表</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 引入 Bootstrap -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>人员列表 —— 显示所有人员</small>
                </h1>
            </div>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12 column">
            <table class="table table-hover table-striped">
                <thead>
                <tr>
                    <th>用户名</th>
                    <th>年龄</th>
                    <th>手机号</th>
                    <th>邮箱</th>
                    <th>兴趣爱好</th>
                </tr>
                </thead>

                <tbody>
                <c:forEach var="person" items="${requestScope.get('personList')}">
                    <tr>
                        <td>${person.getUsername()}</td>
                        <td>${person.getAge()}</td>
                        <td>${person.getPhone()}</td>
                        <td>${person.getEmail()}</td>
                        <td>${person.getHobby()}</td>
                    </tr>
                </c:forEach>
                </tbody>
            </table>
        </div>
    </div>
</div>

4 web.xml配置注册DispatcherServlet

然后我们将中心控制器注册到web.xml,用来启动时读取:

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>
        <!--1.注册DispatcherServlet-->
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--关联一个springMVC的配置文件:【servlet-name】-servlet.xml,注意,我们这里关联的是主入口的配置文件-->
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--启动级别-1,在Tomcat启动时就初始化Spring容器-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--encodingFilter-->
    <filter>
        <filter-name>encodingFilter</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>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--Session过期时间-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>
</web-app>

5 springmvc-servlet.xml核心配置编写

springmvc-servlet.xml核心配置我们用spring-mvc.xml来替代。

6 spring-mvc.xml整合配置编写

MVC的核心配置即是springmvc-servlet.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
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描controller相关的bean,自动注入Spring-->
    <context:component-scan base-package="com.example.ssm_frame.controller"/>

    <!-- 让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />

    <!--支持mvc注解驱动-->
    <mvc:annotation-driven />

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

SSM框架整合

三个框架的主体都编写完毕后,我们来整合框架并做测试

1 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="spring-configs/spring-dao.xml"/>
    <import resource="spring-configs/spring-service.xml"/>
    <import resource="spring-configs/spring-mvc.xml"/>

</beans>


2 配置Tomcat服务器

然后我们配置Tomcat服务器:
在这里插入图片描述

3 启动服务器并进行测试

最后我们在浏览器请求访问然后看展示的效果:
在这里插入图片描述
同时通过日志我们从后台也能看到执行过程:
在这里插入图片描述

总结一下

这样就整合完成了SSM框架用来实现了一个简单的需求,事实上无论是早年间的Servlet+JSP+JDBC或是后来的SSH框架直至今天的SSM框架,其完成的功能都是固定的,例如JDBC、Hibernate和MyBatis完成的工作是数据持久化,它们都需要处理数据缓存、连接池、结果集映射、查询参数绑定等问题,但随着技术的发展,实现的成本越来越低;Servlet、Struts和SpringMVC都充当了(中心)控制器的功能,它们都需要处理事务、文件上传下载、请求转发、重定向、过滤器、监听器等问题,同样随着技术的发展,实现的成本越来越低;Spring呢作为后来的整合老大哥,通过IOC技术接管了各种类和各种框架,让所有的框架从大杂烩成为了一体,更好的服务于开发者。技术从来就是用来解决业务问题的,哪种实现方式更简单,我们用哪种,但不仅要知道怎么用还要知道为什么用,这才是重点。

评论 6 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:Age of Ai 设计师:meimeiellie 返回首页

打赏作者

存在morning

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值