0%

SSM框架总结

SSM框架的一些基本知识总结。

1.SSM定义

SSM = Spring + SpringMVC + MyBatis
Spring:
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

SpringMVC命名及分层:
edu.xju.common.util 公共部分
edu.xju.controller 控制层
edu.xju.dao 数据层
edu.xju.entity 实体层
edu.xju.service 服务层

MyBatis:
比Hibernate要灵活多用于需求不断变更的项目。

2.Web项目执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!-- 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">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</context-param>
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<!-- 如果使用如下配置,Spring Web MVC框架将加载“classpath:spring-mvc.xml”来进行初始化上下文而不是“/WEB-INF/[servlet名字]-servlet.xml”。 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 传给上下文实例(由contextClass指定)的字符串,用来指定上下文的位置。这个字符串可以被分成多个字符串(使用逗号作为分隔符) 来支持多个上下文(在多上下文的情况下,如果同一个bean被定义两次,后面一个优先)。 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- load-on-startup:表示启动容器时初始化该Servlet; -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“*.html”表示拦截所有以html为扩展名的请求。 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<welcome-file-list>
<!-- 从main.jsp开始 -->
<welcome-file>main.jsp</welcome-file>
</welcome-file-list>
</web-app>

DispatcherServlet拦截所有请求,在这里是拦截.do和.json结尾的请求。
该DispatcherServlet默认使用WebApplicationContext作为上下文,Spring默认配置文件为“/WEB-INF/[servlet名字]-servlet.xml”。
ContextLoaderListener初始化的上下文和DispatcherServlet初始化的上下文关系
初始化上下文关系
ContextLoaderListener初始化的上下文加载的Bean是对整个应用程序共享的;
DispatcherServlet初始化的上下文加载的Bean是只对Spring Web MVC有效的Bean;即只加载Web相关的组件。
DispatcherServlet的继承关系
DispatcherServlet继承关系

DispatcherServlet initialization parameters
![DispatcherServlet initialization parameters](/assets/blogImg/DispatcherServlet initialization parameters.png)

  1. HttpServletBean继承HttpServlet,因此在Web容器启动时将调用它的init方法,该初始化方法的主要作用
    将Servlet初始化参数(init-param)设置到该组件上(如contextAttribute、contextClass、namespace、contextConfigLocation),通过BeanWrapper简化设值过程,方便后续使用;提供给子类初始化扩展点,initServletBean(),该方法由FrameworkServlet覆盖。
  2. FrameworkServlet继承HttpServletBean,通过initServletBean()进行Web上下文初始化,该方法主要覆盖一下两件事情:
    初始化web上下文;
    提供给子类初始化扩展点;
  3. DispatcherServlet继承FrameworkServlet,并实现了onRefresh()方法提供一些前端控制器相关的配置;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- 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:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描这个控制包内部的Controller -->
<context:component-scan base-package="edu.xju.controller"/>
<mvc:annotation-driven />
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
</list>
</property>
</bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// spring-mybatis.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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 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"
>

<context:component-scan base-package="edu"/>

<aop:aspectj-autoproxy/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb?charsetEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>

<!--sessionFactory代理-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>

<!--注解扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="edu.xju.dao"/>
<property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
</bean>

<!--spring 事务管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!--定义事务声明 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="serviceAop" expression="execution(* edu.xju.service.*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceAop" />
</aop:config>

</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>基本的 ssm 框架</title>
<style type="text/css">
a{
font-size: 20px;
display: block;
margin-top: 30px;
}
</style>
</head>
<body>
<a href="${pageContext.request.contextPath }/user/addUser.do">添加用户</a>
<a href="${pageContext.request.contextPath }/user/list.do">查找所有用户</a>
<a href="${pageContext.request.contextPath }/user/getUserA.json?id=1">获取某个用户JSON格式1</a>
<a href="${pageContext.request.contextPath }/user/getUserB.json?id=2">获取某个用户JSON格式2</a>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// UserController.java
package edu.xju.controller;

import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import edu.xju.common.util.JsonUtil;
import edu.xju.entity.User;
import edu.xju.service.UserService;

@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 这个是返回页面
* @param model
* @return
*/
@RequestMapping("/list.do")
public String getUsers(Model model,HttpSession session){
List<User> users = userService.getAll();
model.addAttribute("list",users);
return "list";
}

/**
* 获取json 的第一种方式
* 返回json 格式
* @param model
* @param session
* @param id
* @return
*/
@RequestMapping("/getUserA.json")
@ResponseBody
public Object getUserByIdA(Model model,HttpSession session,Integer id ){
User user = userService.findUserById(id);
return user;
}

/**
* 获取第json 的第二种方式
* @param model
* @param response
* @param session
* @param id
*/
@RequestMapping("/getUserB.json")
public void getUserByIdB(Model model,HttpServletResponse response,HttpSession session,Integer id ){
User user = userService.findUserById(id);
JsonUtil.printByJSON(response, user);
}

@RequestMapping("/addUser.do")
public String insertUser(Model model,HttpSession session,Integer id,String name,Integer age ){
name = "测试姓名";
age = 99;
User user = new User(name, age);
userService.addUser(user);
return "insertOK";
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// User.java
package edu.xju.entity;

public class User {
private Integer id;
private String name;
private int age;
public User() {
}

public User( String name, int age) {
this.name = name;
this.age = age;
}


public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
// UserService.java
package edu.xju.service;

import java.util.List;

import edu.xju.entity.User;

public interface UserService {
public List<User> getAll();
public User findUserById(Integer id);
public void addUser(User user);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// UserServiceImpl.java
package edu.xju.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import edu.xju.dao.UserMapper;
import edu.xju.entity.User;

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;

public List<User> getAll(){
return userMapper.getAll();
}

@Override
public User findUserById(Integer id) {
return userMapper.getUserById(id);
}
@Override
public void addUser(User user) {
userMapper.insertUser(user);
}
}

MyBatis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// UserMapper.java
package edu.xju.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import edu.xju.entity.User;

@Repository
public interface UserMapper {
public List<User> getAll();
public User getUserById(@Param("id")Integer id);
public void insertUser(User user);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// UserMapper.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="edu.xju.dao.UserMapper" >
<!-- 声明属性与查询字段之间的的对应关系 -->
<resultMap id="BaseResultMap" type="edu.xju.entity.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
</resultMap>
<select id="getAll" resultMap="BaseResultMap">
select id,name,age from user
</select>

<select id="getUserById" parameterType="int" resultMap="BaseResultMap">
select id,name,age from user where id = #{id}
</select>
<insert id="insertUser" parameterType="edu.xju.entity.User">
insert into user(name,age) values(#{name},#{age})
</insert>
</mapper>

3.序列图

流程序列图

4.常用注解解析:

@Autowired 和 @Resource的使用场景和区别

@Autowired 是byType自动注入,是Spring的注解。@Resource默认是byName注入,默认使用成员属性的变量名注入,是Java自带的注解。

@Scope(“prototype”) 和 @Scope(“singleton”) 的区别

singleton 表示Spring容器中的单例,通过spring 容器获取该bean时总是返回唯一的实例。
prototype 表示每次获取该bean时都会new 一个新的对象实例。

1
2
3
4
5
6
@Service
@Scope("singleton")
public class SingletonTestService {
private static int a = 0;
private int b = 0;
}

如代码所示,如果设置为singleton,当a++和b++时,a和b都会增加。如果设置为prototype的话,则只有a会增加,b不会增加。

static 静态变量

静态变量整个内存中只有一个副本,为所有对象所共享,当且仅当类加载时才会被初始化;而非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本,每个对象之间拥有的副本互不影响。