从空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/javaeehttp://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-jdbc Spring的jdbc集成组件
mysql-connector-java MySQL数据库的jdbc组件
commons-dbcp 连接池,用来做数据源dataSource
mybatis mybatis核心类,提供mybatis的sqlSessionManage
mybatis-spring mybatis与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
到底啦