从空Pom文件用最少依赖配置SSM框架

从头开始 好多Web开发者都没有从头开始部署过SSM框架,网上一些教程总是加了一堆 常用但不是必须 的配置 本文旨在最少配

从头开始

好多Web开发者都没有从头开始部署过SSM框架,网上一些教程总是加了一堆 常用但不是必须

的配置

本文旨在最少配置和依赖的情况下,构建起一个基于SpringMVC+Spring+MyBatis的Maven工程。

基于Maven的Web工程

当我们新建一个空的Maven工程的时候,仅有一个pom文件,一个source目录,一个resource目录,参考Java工程目录文章

加入Web目录

此时我们要使得这个工程变成Web工程,所以在source和resource同级的地方加入webapp目录

---main

---java

---resource

---webapp

---WEB-INF

---web.xml

其中根据文章Web.xml是什么可知,WEB-INF 和 web.xml 是由J2EE工程规定的,不能随意更改,web.xml是Servlet的配置,如何从头开始写呢?应该使用哪个版本呢?

这个可以去你下载的Servlet服务器容器的 /etc

目录中找到 webdefault.xml

该文件的xml命名空间里说明了该版本容器支持哪个版本的Servlet

例如Jetty8支持的是Servlet2.5 而 Jetty9则是3.0,此时我们得到了两个空的配置文件pom.xml和web.xml

空配置文件

pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>person.test</groupId>

<artifactId>spring</artifactId>

<version>1.0</version>

</project>

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_3_1.xsd"

metadata-complete="false"

version="3.1">

</web-app>

加入工程Target

完成了Web工程配置,此时我们要在pom.xml告诉Maven我们要 编译——汇编——链接

成什么东西,也就是Target叫什么和用什么格式

<project ...>

.....

<packaging>war</packaging> <==该模块打包成war包即WebApp的程序

<build>

<finalName>spring</finalName> <==最后程序名叫spring

</build>

</project>

SpringMVC+Spring

在完成了Web工程的配置之后,我们开始引入SpringMVC+Spring

修改依赖

在pom.xml文件中加入SpringMVC的依赖,不用添加spring-core因为SpringMVC会自己引用spring-core

<project ...>

....

<dependencies>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>4.3.3.RELEASE</version>

</dependency>

</dependencies>

</project>

配置SpringMVC作ServletDispatch转发器

修改web.xml 原理参考Servlet原理把SpringMVC作为主入口的转发器,

org.springframework.web.servlet

包属于spring-webmvc这个Jar包

<servlet>

<servlet-name>springMVC</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>

</servlet>

<servlet-mapping>

<servlet-name>springMVC</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

此处的 contextConfigLocation

位于 DispatcherServlet的父类FrameworkServlet的第65行 private String contextConfigLocation

所以说spring-mvc.xml是对DispatcherServlet的配置

配置Spring作为Servlet的监听器

在搭建基于SpringMVC的Web服务时,Spring本身并不是必须添加的也就是说applicationContext.xml和listener也不是必须存在,具体原因我们在后边讨论

org.springframework.web.context

包属于spring-web这个Jar包

也就是说我们常说的SSH或SSM中的spring配置其实是指的配置spring-web服务而不是spring-core这个IOC容器

<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>

此处的 contextConfigLocation

位于 ContextLoaderListener的父类ContextLoader的第176行 configLocationParam = sc.getInitParameter(“contextConfigLocation”)

通过同名字符串获取到的configLocationParam 所以说applicationContext.xml是对ContextLoaderListener的配置

配置spring-mvc.xml

如果想让SpringMVC正式提供Web服务,需要以下几个 必要配置

注意在加入mvc命名空间后,需要有对应的xmlns,一般来讲intelliJ IDEA会自动补全

<beans ......>

<mvc:default-servlet-handler/> <==让SpringMVC作为默认的Servlet处理器

<mvc:annotation-driven/> <==让SpringMVC使用注解驱动,即可用RequestMap一类的注解

<context:component-scan base-package="person.zhuojia.learn.spring"/> <==让SpringMVC的Java文件基础包名

</beans>

配置applicationContext.xml

由于我们没有任何需要Spring控制的Class,所以applicationContext文件内容可以留空

<?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>

Mybatis

首先明确,Mybatis是JDBC的一个封装,所以说其本身无法离开JDBC,所以说我们要准备一些依赖,其配置可以放在任意一个Context里

依赖的准备

依赖名称作用
spring-jdbcSpring的jdbc集成组件
mysql-connector-javaMySQL数据库的jdbc组件
commons-dbcp连接池,用来做数据源dataSource
mybatismybatis核心类,提供mybatis的sqlSessionManage
mybatis-springmybatis与Spring集成的组件

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>${mysql.version}</version>

</dependency>

<dependency>

<groupId>commons-dbcp</groupId>

<artifactId>commons-dbcp</artifactId>

<version>${dbcp.version}</version>

</dependency>

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>${mybatis.version}</version>

</dependency>

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis-spring</artifactId>

<version>${mybatis-spring.version}</version>

</dependency>

连接池配置

首先我们需要在Spring中启动连接池作为dataSource,而驱动(Driver)就是使用由spring-jdbc和mysql-connector一起提供的 com.mysql.jdbc.Driver

当我们输入数据库和账号密码,一个默认的连接池就启动好了

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://127.0.0.1:3306/psas?useUnicode=true&characterEncoding=utf8"/>

<property name="username" value="root"/>

<property name="password" value="root"/>

</bean>

MybatisSpring配置

配置好连接池后,参照MyBatisSpring的配置进行如下配置

配置完毕后就可以使用 DOMapper.java DO.java 和DOMapper.xml进行持久层封装

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource"/>

<property name="mapperLocations">

<list>

<value>classpath:*Mapper.xml</value>

</list>

</property>

</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<property name="basePackage" value="person.zhuojia.learn.spring.dal"/>

<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>

</bean>

结语

以上是用最少的配置来实现SSM框架,其中很多优化参数都给省去了,具体优化设置请参考其它文章

『重中之重』

applicationContext和spring-mvc配置文件的区别

Spring本身可以提供多个Context,根据 StackOverflow的回答

回答,当我们需要多个Servlet而不是一个的时候,可以针对不同的Servlet设置不同的配置文件servlet-1.xml、servlet-2.xml,这是在SpringMVC的DispatcherServlet

如果有servlet1和servlet2公用的部分,可以通过配置ContextLoaderListener作为Root Context以供所有servlet使用,其由Jar包spring-web来实现

Root Context和Servlet Context的区别

由于Root Context是作为公用区域存在的,所以说就导致一个重要的特性Root Context的Beans可以被不同的Servlet的Bean引用(Reference),但其本身的Bean却不能引用Servlet的Bean

为什么大家都写Root Context

在早先的SSH框架时,准确的说指的是 Struts2 + SpringWeb + Hibernate,由于不能Struts2不能配置ServletContext,所以需要applicationContext配置文件

而使用了 SSM (SpringMVC SpringWeb Mybatis) 之后,为什么不能继续使用applicationContext,还要spring-mvc或者说servletContext这个配置呢?因为SpringMVC的Controller必须配置在servletContext中,加上好多人并不知道 在单一Servlet下Root Context也就是applicationContext是多余的

由此产生的一系列问题

这个问题坑过我好多回,当时不明白为什么现在可以意义解释了

  1. SpringMVC和Spring配置导致事务失效

    : 因为事务管理器transactionManager是声明在Root Context,而不区分包名导致ServletContext拿到了所有@Service的Bean,为什么是ServletContext拿到,是因为Servlet作为子Context优先级高啊,那么transactionManager就没办法引用@Service导致事务失效

  2. Shiro的注解配置位置不对

    : 如果想用Shiro的注解对Controller控制,那么必须能对Controller加动态代理,如果按照官方文档放在applicationContext里,自然没办法引用在子Context的@Controller的Class

未登录用户
全部评论0
到底啦