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
| <?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> <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>*.do</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.json</url-pattern> </servlet-mapping> <welcome-file-list> <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 initialization parameters
![DispatcherServlet initialization parameters](/assets/blogImg/DispatcherServlet initialization parameters.png)
- HttpServletBean继承HttpServlet,因此在Web容器启动时将调用它的init方法,该初始化方法的主要作用
将Servlet初始化参数(init-param)设置到该组件上(如contextAttribute、contextClass、namespace、contextConfigLocation),通过BeanWrapper简化设值过程,方便后续使用;提供给子类初始化扩展点,initServletBean(),该方法由FrameworkServlet覆盖。
- FrameworkServlet继承HttpServletBean,通过initServletBean()进行Web上下文初始化,该方法主要覆盖一下两件事情:
初始化web上下文;
提供给子类初始化扩展点;
- 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
| <?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"> <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>
<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>
<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
| 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;
@RequestMapping("/list.do") public String getUsers(Model model,HttpSession session){ List<User> users = userService.getAll(); model.addAttribute("list",users); return "list"; }
@RequestMapping("/getUserA.json") @ResponseBody public Object getUserByIdA(Model model,HttpSession session,Integer id ){ User user = userService.findUserById(id); return user; }
@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
| 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
| 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
| 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
| 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 静态变量
静态变量整个内存中只有一个副本
,为所有对象所共享,当且仅当类加载时才会被初始化;而非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本
,每个对象之间拥有的副本互不影响。