SSM通俗理解
作为一名持续学习中的小白,今天在同学的帮助下搭建了一个SSM(Spring、SpringMVC、Mybatis)框架,但是作为新手来说理解框架实在过于困难,故在此写下SSM框架的个人理解,供和我一样的小白学习理解框架,如果不妥之处,还望各位大神斧正。
先看idea文件结构:
bookshop是自己随便想的项目名字,可忽略。
我们先来看Java下的Bean目录,里面只有一个User文件,内容为
package com.zs.Bean;
public class User {
private
String id = "";
String username = "";
String email = "";
String password = "";
public User(String id, String username, String email, String password) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + username + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
}
这个文件对应映射数据库中的User表,可以把它理解为数据库中每一个记录的数据结构,就是用来承接数据库记录的数据结构。
再来看Dao下的UserDao文件,内容为:
package com.zs.Dao;
import com.zs.Bean.User;
import java.sql.ResultSet;
import java.util.List;
public interface UserDao {
public abstract List<User> SAll();
public abstract boolean Add();
public abstract boolean Del();
public abstract boolean Upd();
public abstract User Search();
}
这是一个接口,提供了对user表的增删改查的方法,熟悉Spring框架的同行可能知道,这个接口的方法在整个项目中并未显示继承或者实现。这里就需要用到Mybatis框架,Mybatis框架使用mapper.xml文件实现对这些虚方法的具体化,这里我们看mapper文件夹下的user.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.zs.Dao.UserDao" >
<select id="SAll" resultType="com.zs.Bean.User" >
select * from users;
</select>
</mapper>
逐行分析代码,代码头文件我们暂时抛开,mapper标签中,namespace为UserDao文件,也就是上面的接口代码,在这里,Mybatis使用id表示的方法名来对方法进行填充,这里可以看到,SALL方法被填充为全查询。
再接着看Service下面的UserDaoService文件,里面也是一堆虚方法,我们不用关心具体是什么方法,直接看Imp包下的UserDaoImp文件,如下:
@Service
public class UserDaoImp implements UserDaoSeverice {
@Autowired
UserDao userDao;
@Override
public List<User> SAll() {
return userDao.SAll();
}
@Override
public boolean Add() {
return false;
}
@Override
public boolean Del() {
return false;
}
@Override
public boolean Upd() {
return false;
}
@Override
public User Search() {
return null;
}
}
这这里我们看到,这个实现接口的方法即将被Spring解析为Service类型,因为该类实现接口,所以必须实现接口的所有方法,再来,我们看到该类里面有一个UserDao对象,该对象是一个接口对象,按照java标准,他是不可实例化的。但是Spring框架提供的Autowired标识符意味着这个对象将被Spring自动注入,也就是说,这个接口目前是可以实例化并且调用里面的方法的。
再往下看,该类的方法中调用了UserDao实例化的方法。这里因为是演示,所以UserService中的接口方法和UserDao名称相同,但是在实际项目中是可以不同的。
到这里,我们就可以理清楚了数据库到Bean到Dao到Service的操作,业务逻辑层的方法通过结构给到实现类,实现类中自动注入UserDao的实例化对象。
再来看Controller包,里面有一个UserController文件,文件内容为:
package com.zs.Controller;
import com.zs.Bean.User;
import com.zs.Service.UserDaoSeverice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
@RequestMapping("user")
public class UserController{
@Autowired
UserDaoSeverice userService;
@RequestMapping("SAll.do")
public ModelAndView SAll(){
List<User> users = userService.SAll();
ModelAndView mv = new ModelAndView();
mv.addObject("userList",users);
mv.setViewName("user-list");
return mv;
}
}
首先是Controller标识符,表示这个文件被框架解析为Controller类型,RequestMapper标识符表示这个controller只有在接收到来自路径为”user“的请求时才启用,在这个类里依然自动注入了业务逻辑层,依然是实例化接口类型,在这里,Spring自动将实现此接口的类做控制反转实例化注入该对象中。这个controller的方法SAll在请求路径为”SAll.do“时启用,方法体中,调用业务逻辑层方法,回传查询结果。并通过modelandview对象将结果进一步封装后传到(user-list)页面。
再来看项目启动流程,项目启动后,浏览器默认跳转到index.jsp,该文件有一个a标签,点击后将请求路径跳转为(…/user/SAll.do),这个时候需要注意,在web.xml文件中,最后一个标签,他表示,任何以 .do结尾的请求都会触发dispatcherServlet,这个Servlet启动后会,加载springmvc.xml配置文件,这个配置文件时SpringMVC的配置文件,他会执行一系列的加载操作,识别Controller文件,并加载过滤器拦截器等组件。SpringMVC初始化以后,该请求继续发送到servlet,这里我们注意,因为路径是/user/SAll.do,所以,/user/会触发UserController这个控制器,又有/SAll.do路径,所以该请求又会触发该控制器中的SAll方法(这个方法名也是纯属巧合),在这个方法里,数据库中的纪录被取出封装到ModelAndView中,送到(pages/user-list.jsp)进行解析。
至此,浏览器请求-》controller触发-》Service启动-》数据库查询-》结果封装回传-》结果送到相应页面已经完成。剩下的工作就是页面解析数据并回传给浏览器进行显示。
最后一步,页面解析,在user-list.jsp页面中,使用了c标签,该标签的具体作用类似于js脚本,可以在页面解析时执行,modelAndView对象在回传数据时,将数据重命名为userList,所以jsp页面收到的就是名为userList的数据,再看页面中c标签部分,它使用for each语法,逐个取出User数据,并使用$表达式将每一个属性取出并进行标签封装显示,然后将已经用数据填充后的页面发给前台浏览器进行解析,最后可视化的显示出来。
至此,整个SSM框架工作流程梳理完毕。
另外,ApplicationContext.xml文件具体的加载过程应该是在war部署文件生成期间进行加载和解析,以保证整个项目的稳定性。Spring-MVC.xml文件理论上讲也应该是在生成war文件时加载,但是根据代码注释来看应该是请求到来时加载。