SSM項目整合紀實

一  前 言

  原本是爲了探究一些功能性問題,須要一套完整的項目架構,本覺得SSM用過那麼多了,輕鬆搭建不在話下,可是過程當中仍是遇到一些問題,踩到一些不曾料想的坑。博文以搭建極簡架構爲目的,附帶一些關鍵闡述,既是備忘,也是分享。html

二  Maven奠定

  IDEA中用 Maven 的方式搭建 web 項目的時候若是你選擇了 web 項目骨架,那麼最終生成的項目目錄結構是很不標準的一個目錄結構,而若是不選擇 web 項目骨架,產生的項目目錄標準但卻少了 web 目錄。固然,基於IDEA的強大,確定不至於讓你手動去整理包結構,請按如下簡單步驟操做便可:前端

  沒有選擇骨架的Maven項目結構以下——java

  而後項目右鍵 Add Frameworks Support 添加 web 支持——mysql

三  Java 配置集成 Spring+Spring MVC

  一般的作法是須要在 web.xml 中配置 Spring 初始化上下文的監聽器 ContextLoaderListener 和 Spring MVC的核心 DispatcherServlet,它們會加載各自路徑中的xml配置文件來產生各自的上下文對象。不過博主並不想這麼作,而是採用純 Java 配置的方式,因此本項目示例中沒有 web.xml的存在。經過Java配置的方式,咱們須要兩個配置類,一個配置類擴展 WebApplicationInitializer 接口的派生類 AbstractAnnotationConfigDispatcherServletInitializer ,其會同時建立 ContextLoaderListener 和 DispatcherServlet 的上下文,並根據須要配置 DispatcherServlet 的映射路徑和相關配置類:web

public class BluesInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    //給定的Java 配置類將定義 ContextLoaderListener 上下文中的 bean 實例 本示例中沒有給出根配置類
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    // 給定的Java 配置類將定義 DispatcherServlet 上下文的bean 實例
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class}; 
    }

    // 配置一個或多個 映射路徑
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

  另外一個就是MVC的基礎配置類——spring

@Configuration
@ComponentScan(basePackages = {"net"})
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    //配置視圖解析器
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    /**
     * 經過繼承 WebMvcConfigurerAdapter 類的方式配置靜態資源請求
     * 將對靜態資源的訪問交由容器中默認的 Servlet 處理
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        /** 至關於 xml 配置中的 <mvc:default-servlet-handler /> 配置 */
        configurer.enable();
    }
}

  完成兩個配置類後其實Spring和Spring MVC就已經配置完了,你能夠編寫控制器作頁面跳轉測試,這裏限於篇幅博主再也不貼出。想要知道爲何能用以上的Java配置取代常常用的 web.xml中的配置 ,首先你必須得清楚 web.xml 中的 ContextLoaderListener 和 DispatcherServlet 的做用。關於這二者的深層理解,可參考一位博友的源碼分析,這裏博主仍是按照己的理解來敘述:               sql

  ContextLoaderListener 是Spring的一個監聽器,當其監聽到容器啓動會根據定義文件(能夠理解爲建立 bean 實例及維護bean依賴關係的圖紙,默認是WEB-INF下的applicationContext.xml文件)建立Spring的上行下對象,也即容器對象,有了該容器對象程序運行時才能從容器中獲取到bean; DispatcherServlet 本質就是一個Servlet ,因此,Servlet容器啓動時天然會將其初始化(<load-on-startup>配置爲正數),關鍵這傢伙是 Spring 的,功能很強大,也可以根據本身的 xml定義文件(默認 WEB-INF下的【servlet-name】-servlet.xml)產生一個上下文對象,這個上下文容器對象負責管理維護Spring MVC生態體系中的 控制器啊,視圖解析器,處理映射器等bean;這兩個容器對象有關係嗎,固然有關係,能夠粗淺的理解爲父子關係,前者是整個應用的根容器對象,是全局的,後者只是管理應用於Servlet相關組件。數據庫

    而爲何擴展了AbstractAnnotationConfigDispatcherServletInitializer 類就能完成上述相同的功能呢?由於在Servlet 3.0 規範中,爲第三方組件提供了一個叫 ServletContainerInitializer 的接口用來作一些初始化相關的工做,第三方組件只要實現此接口就能夠完成本身的一些初始化操做。在Spring中提供的實現類叫 SpringServletContainerInitializer ,追蹤源碼,你能夠發現,真正的初始化配置實際上是交給 WebApplicationInitializer 接口的子類來完成的,而上面代碼中的 AbstractAnnotationConfigDispatcherServletInitializer 就是WebApplicationInitializer 接口的子類,因此,咱們能夠繼承該類,根據業務需求重寫相應的方法,來完成咱們初始化Spring 和Spring MVC 上下文的相關配置。至此,我想你應該能看懂上面的配置是什麼意思以及和web.xml中的配置的對應關係了。apache

四  整合Mybatis

  持久層的整合無需多說,在資源文件夾下新建 spring-mybatis.xml 和 db.properties文件,依次配置鏈接數據庫的數據源(應該從 db.properties中獲取數據庫鏈接信息 )、生成SqlSession 的 SqlSessionFactory定義(其依賴於數據源和mapper.xml文件路徑)以及映射器配置類 MapperScannerConfigurer。db.propertie和spring-mybatis.xml 配置文件以下:json

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sql_eve?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
<?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"
       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 ">

    <!--加載數據庫配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置數據源 這裏是配置的druid 鏈接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!-- 配置初始化鏈接池大小設置 -->
        <property name="initialSize" value="1" />
        <!--最小空閒鏈接數量,設 0 沒有限制 -->
        <property name="minIdle" value="1" />
        <!--最大活動鏈接數量,設 0 沒有限制-->
        <property name="maxActive" value="5" />
        <!--從池中獲取鏈接的最大等待時間,單位ms-->
        <property name="maxWait" value="10000" />
    </bean>

    <!--配置 SqlSessionFactory 全局單例 一個數據庫應該只對應一個 SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>
    <!--配置 MapperScannerConfigurer 來配置映射器,經過掃描相應包下的接口生成動態代理對象交由Spring 管理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="net.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
</beans>

 

  如今這個配置文件Spring容器是不知道的,須要在上面的Java配置類WebConfig上標註 @ImportResource("classpath:spring-mybatis.xml") 進行引入。而後,來一個mapper.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="net.dao.ProductDao">
    <select id="queryProducts" resultType="net.entity.Product">
            select * from products
    </select>
</mapper>

五  避坑指南

  ① IDEA編譯問題

  有時候咱們可能會將mapper.xml文件寫在dao下面的mapper包裏,可是在IDEA的Maven項目中,編譯器只會對java包下面.java文件進行編譯處理,而忽略掉其中的資源文件,在運行時就會找不到相應的配置文件。因此資源文件最好直接放在resources目錄中,若是確實須要放在java目錄中,需在pom.xml中配置(配置連接)。

  ② 缺乏 jdbc 支持異常

  ③ 返回參數類型錯誤

 

 附 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>com.buyi</groupId>
    <artifactId>blues</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring.version>4.3.7.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--spring mvc 依賴引入,由於相互依賴的關係,實際上也就引入了 Spring 的幾大核心包,不須要單獨的引入 core beans之類的依賴-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--spring-jdbc 支持-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

 
        <!--json支持 缺乏會致使返回前端json格式數據的時候出錯 java.lang.IllegalArgumentException: No converter found for return value of type: class ...-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.5.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>

<!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.2</version> </dependency> <!--spring-mybatis整合包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!--數據庫驅動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> <scope>runtime</scope> </dependency> <!--數據庫鏈接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.12</version> </dependency> <!--測試支持--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--websocket 支持--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project>
相關文章
相關標籤/搜索