概述
目前主流一种搭配方案,SSM,而不是 SSH,并且其中的 SS 都是 Spring 产物,其中不再为 Struct 保留位置。
这种方案除了其中 Spring 本身位置没有变动,其余两个更改了霸主地位。
不说历史,毕竟没有经历过。
Spring 与 SpringMVC 关系
可以看到 SSM 中,包含了这两个部分,它们之间是可以用父子关系来形容,SpringMVC 是专用于 Web 相关的开发所用,而 Spring 更专注于业务处理。
Spring 包含了所有核心技术,其它的框架都是依赖 Spring 框架的核心技术。
SpringMVC 在 Java 原生的 Servlet API 基础上进行扩展。
也就是说,Spring 与 SpringMVC 很多功能都是共同的,SpringMVC 包含 Spring 的功能,那么有必要在使用 Spring 框架吗?
简单说下,如果单独使用 SpringMVC 框架,那么就代表着将所有的业务逻辑,第三方框架的加载,还有数据库配置等等都需要在 SpringMVC 配置文件中定义,这样就会出现繁杂的配置,所有配置都放在 SpringMVC 层框架配置。要知道这个框架就是用来开发 web 的,按照这样配置的话,就不仅仅的 web 业务,而是将各种技术都放在了一起。
这样加上 Spring 框架,来负责:
- 第三方框架的整合
- 数据源配置
- DAO
- Serivce
- 事务
- Spring 配置
而 Spring MVC 只要负责:
- 静态资源
- 视图解析器
- 所有与 mvc 相关的配置
既然将两者的负责范围进行了区分,那么在技术层面如何进行?
- 如何初始化容器?
- 如何各自负责范围?
关于第一个问题:可以使用监听器来解决,在 Servlet 容器启动的时候,就加载 Spring 容器。
第二个问题:还记得 xml 配置方式的扫描包的属性,其中有个 use-default-filter 和两个子标签来进行排斥处理。
Spring 配置
按照上面所描述的,只需要加载负责范围的。
使用 listener 来初始化容器,首先可以自定义的方式,创建一个监听类,实现 ServletContextListener 接口,并且在 contextInitialized 方法中实例化 ClassPathXmlApplicationContext 类。
public void contextInitialized(ServletContextEvent sce) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("ioc", ioc);
}
接着在 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_4_0.xsd"
version="4.0">
<listener>
<listener-name>MyListener</listener-name>
<listener-class>com.huasio.listener.MyListener</listener-class>
</listener>
<listener-mapping>
<listener-name>MyListener</listener-name>
<url-pattern>/*</url-pattern>
</listener-mapping>
</web-app>
这样,在 Servlet 容器启动的时候,就会调用监听器的方法,并且在程序运行期间,都能使用 ioc 实例。
这种方式除了有些繁琐之外,还有一种方式,是 Spring 自身提供的。只需要在 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_4_0.xsd"
version="4.0">
<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>
</web-app>
那么要是在程序中需要用到容器怎么获取?
通过源码,找到这么一行:
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
通过 "org.springframework.web.context.WebApplicationContext.ROOT" 就可以从 "ServletContext" 里面获取到整个 ioc。
初始化问题解决之后,接下来就是如何区分职责配置了。目前整个方案,对基础的进行配置,那么在 Spring 就要配置 Mybatis。
用到的依赖包:
- spring 本身
- mybatis
- spring-mybatis 整合工具
- driud 也就是数据源
- mysql 驱动
- log4j
- 这个只要将配置文件放在能被解析到类路径就行,spring 会自动寻找名为:log4j.xml 的配置文件。
要配置的东西有:
- 排斥扫描组件
- druid 也就是数据源
- Mybatis 配置
<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
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://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
<!-- 排次扫描组件 -->
<!-- 排除 @Controller 注解的组件 -->
<context:component-scan base-package="***">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 配置 Druid 数据源 -->
<!-- 引入外部 properties 配置文件 -->
<context:property-placeholder location="classpath:applicationContext.xml" />
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="url" value="${jdbc.url}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="maxWait" value="${jdbc.maxWait}" />
<property name="minIdle" value="${jdbc.minIdle}" />
</bean>
<!-- 配置 Mybatis -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" value="dataSource" />
<!-- mapper 配置文件 -->
<property name="mapperLocations" value="classpath:mybatis/*.xml" />
<!-- 加载 Mybatis 全局配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<!-- 扫描 mapper 接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.huasio.crowdfunding.mapper"/>
</bean>
</beans>
与 Mybatis 整合,需要用到 Spring 提供的一个 spring-mybatis 依赖。
对于一些 Mybatis 的配置,仍然可以在 mybatis 的全局配置文件中配置,因为在 spring 的配置文件加载了。
目前来看,整合的必要,就不用写一个接口到 mybatis-config.xml 声明一个 mapper 接口,因为这里自动扫描 mapper 配置文件和 mapper 接口。
对于获取 mybatis 实例,仍然是通过 spring ioc 容器来获取,还记得上面说过得可以从 ServletContext 获取 ioc 容器吗,就是这样操作的。
当然,还是使用注解自动装配的 DAO 更简便。
log4j 配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n"/>
</layout>
</appender>
<logger name="java.sql">
<level value="debug"/>
</logger>
<logger name="org.apache.ibatis">
<level value="info"/>
</logger>
<root>
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>
SpringMVC
配置好了 Spring 的负责的访问,接下来 SpringMVC 就简单多了。
需要用到的依赖:
- spring-mvc
目前需要配置:
- 排斥组件加载
- 加载注解驱动
- 前端核心控制器
- 视图解析器
- 静态资源加载
- 请求编码字符集
- RESTful
挺多的,比 spring 还多,实际并不是。 SpringMVC 要配置东西没有那么多,一些用到的时候才会配置。
首先还是一样,在 web.xml 配置文件,需要将前端核心控制器初始化加载,然后配置请求编码字符集、RESTful等。
<?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_4_0.xsd"
version="4.0">
<!-- 前端核心控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 定义 springMVC 配置文件 -->
<!-- 默认位置在 WEB-INFO/<servlet-name>-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!-- Servlet 容器启动就加载类 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- POST 请求编码设置 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncoding</filter-class>
<init-param>
<!-- 强制设置编码 -->
<!-- 在 5.0 的时候不是这个属性 -->
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- RESTful 配置 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
初始化的配置就配置好了,接下来就是在 SpringMVC 配置文件。
<?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: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="***.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 视图解析器 -->
<bean id="" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INFO/views/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 加载注解驱动 -->
<mvc:annotation-driven />
<!-- 配置静态资源加载 -->
<!-- mapping 是虚拟路径 -->
<!-- location 是实际路径 -->
<mvc:resources mapping="/static/**" location="/static/" />
</beans>
就这样,SSM 都配置好了。
Mybatis
这里没什么好配置的了,有什么 Mybatis 的配置就写 mybatis-config.xml 全局配置文件就行,Spring 会自动加载。
Q.E.D.
Comments | 1 条评论