美文网首页
spring与spring mvc集成多种技术构建复杂工程

spring与spring mvc集成多种技术构建复杂工程

作者: 七弦桐语 | 来源:发表于2016-12-31 17:24 被阅读292次

    使用spring集成其他技术,最基本的配置都是模板化的,比如配置视图模板引擎、数据库连接池、orm框架、缓存服务、邮件服务、rpc调用等,以spring的xml配置为例,我将这些配置过程整理出来,并不时更新,以备参考!

    spring

    在普通的java工程中引入spring,只需要配置以下依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.17.RELEASE</version>
    </dependency>
    

    实际开发中,如果你用了log4j等日志框架,最好排除掉spring对commons-logging的依赖,写demo就不用了

    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
    

    建一个spring-conf.xml,放在src/main/java目录(也就是所有包和类的根目录,即classpath),内容如下

    <?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">
    
        <bean class="com.xmyself.Test" />
    </beans>
    

    建一个Test.java类,这个类就是spring-conf.xml文件中定义的那个bean

    package com.xmyself;
    public class Test {
        public void test() {
            System.out.println("spring is running");
        }
    }
    

    写带有main方法的主类

    package com.xmyself;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
        public static void main(String[] args) {
            @SuppressWarnings("resource")
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml");
            Test test = context.getBean(Test.class);
            test.test();
        }
    }
    

    运行Main,就能看到“spring is running”输出,spring配置完成

    spring mvc

    spring mvc是配置在web工程中的,使用spring mvc也只要配置一个依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>3.2.17.RELEASE</version>
    </dependency>
    

    整一个Test.java类,这是个controller

    package com.xmyself.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class Test {
        @RequestMapping("/test")
        @ResponseBody
        public String test() {
            return "spring mvc running";
        }
    }
    

    在src/main/resources目录下建一个spring目录,里面放一个mvc-init.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:p="http://www.springframework.org/schema/p"
        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:component-scan base-package="com.xmyself.controller" />
    </beans>
    

    这个配置文件扫描了Test.java,最后修改web.xml来加载这个配置文件

    <?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
        <display-name>spring3mvc</display-name>
    
        <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:/spring/mvc-init.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    

    初始化DispatcherServlet如果没有指定xml文件地址,spring默认去WEB-INF目录找[servlet-name]-servlet.xml,这里就是spring-servlet.xml

    启动工程,浏览器访问 http:localhost:8080/springmvc/test 就能看到返回 test 值了,spring mvc配置完成
    freemarker模板引擎

    spring mvc通常要配置模板引擎,因为jsp太复杂了,而且有损mvc模型
    freemarker是一种严格遵循mvc模型的模板引擎,现在介绍它的spring mvc中的配置

    首先配置依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>3.2.17.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>
    

    为什么要依赖spring-context-support?因为freemarker使用的视图解析器是由spring提供的,这个解析器就在spring-context-support的jar中,下面的配置过程会让你明白,在spring mvc的mvc-init.xml中配置freemarker

    <!-- freemarker config -->
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/page/" />
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="suffix" value=".ftl" />
        <property name="contentType" value="text/html; charset=UTF-8" />
    </bean>
    

    配置freemarker的本质是初始化上面的两个bean,所以,你可以把这段配置写在任意的xml文件,只要spring mvc能加载就行

    在WEB-INF目录建一个page目录,里面放一个freemarker.ftl文件,内容只有一句话“freemarker page 中文乱码测试”

    最后,在控制器写一个方法

    @RequestMapping("/freemarker")
    public String freemarker() {
        return "freemarker";
    }
    

    启动工程,访问 http://localhost:8080/springmvc/freemarker 就能看到『freemarker page 中文乱码测试』这句话了

    thymeleaf模板引擎

    thymeleaf也是一个mvc模型的模板引擎,它的后缀是.html,所以thymeleaf模板的好处是不用渲染就能看到内容,现在spring也是推荐用thymeleaf作为spring mvc的模板引擎

    配置依赖

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring3</artifactId>
        <version>2.1.5.RELEASE</version>
    </dependency>
    

    这是thymeleaf与spring连接用的jar,它依赖了thymeleaf的jar,对于spring3和spring4,thymeleaf的依赖是不同的,配置也稍有不同,这点要注意,下面就开始配置thymeleaf

    <!-- thymeleaf config -->
    <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
        <property name="prefix" value="/WEB-INF/page/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML5" />
    </bean>
    <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
    </bean>
    <bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="characterEncoding" value="UTF-8" />
    </bean>
    

    这段配置放在spring mvc能读到的任意xml文件都可以

    在WEB-INF目录建一个page目录,里面放一个thymeleaf.html,内容只有一行“thymeleaf page 中文乱码测试”

    最后,在控制器写一个方法

    @RequestMapping("/thymeleaf")
    public String thymeleaf() {
        return "thymeleaf";
    }
    

    启动工程,访问 http://localhost:8080/springmvc/thymeleaf就能看到“thymeleafpage 中文乱码测试”这句话了

    tomcat pool数据库连接池

    可能用dbcp、c3p0连接池的人多一点,其实tomcat pool更好,具体怎么好请google,下面介绍针对mysql数据库的配置过程

    配置依赖

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.27</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jdbc</artifactId>
        <version>7.0.73</version>
    </dependency>
    

    tomcat-jdbc依赖了tomcat-juli,所以如果你在eclipse中为工程加入了tomcat的库,还需要单独加一个tomcat-juli的jar

    下面整一个Main.java来测试连接

    package com.xmyself;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import org.apache.tomcat.jdbc.pool.DataSource;
    import org.apache.tomcat.jdbc.pool.PoolProperties;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            PoolProperties p = new PoolProperties();
            p.setUrl("jdbc:mysql://localhost:3306/mysql");
            p.setDriverClassName("com.mysql.jdbc.Driver");
            p.setUsername("root");
            p.setPassword("root");
            p.setJmxEnabled(true);
            p.setTestWhileIdle(false);
            p.setTestOnBorrow(true);
            p.setValidationQuery("SELECT 1");
            p.setTestOnReturn(false);
            p.setValidationInterval(30000);
            p.setTimeBetweenEvictionRunsMillis(30000);
            p.setMaxActive(100);
            p.setInitialSize(10);
            p.setMaxWait(10000);
            p.setRemoveAbandonedTimeout(60);
            p.setMinEvictableIdleTimeMillis(30000);
            p.setMinIdle(10);
            p.setLogAbandoned(true);
            p.setRemoveAbandoned(true);
            p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
                    + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
            DataSource datasource = new DataSource();
            datasource.setPoolProperties(p);
            Connection con = null;
            try {
                con = datasource.getConnection();
                Statement st = con.createStatement();
                ResultSet rs = st.executeQuery("select * from user");
                int cnt = 1;
                while (rs.next()) {
                    System.out.println((cnt++) + ". Host:" + rs.getString("Host")
                            + " User:" + rs.getString("User") + " Password:"
                            + rs.getString("Password"));
                }
                rs.close();
                st.close();
            } finally {
                if (con != null)
                    try {
                        con.close();
                    } catch (Exception ignore) {
                    }
            }
        }
    }
    

    这个例子是tomcat官方文档给出的,运行结果如下

    1. Host:localhost User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
    2. Host:127.0.0.1 User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
    3. Host:::1 User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
    4. Host:localhost User: Password:
    5. Host:% User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
    

    那spring怎么集成tomcat pool呢?配置xml让spring加载就好了

    <bean id="datasource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/mysql" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
    

    这里配置的属性与官方例子set方法中的属性完全相同,其余的我就不配置了
    然后写一个测试,这里以spring mvc为例,写一个controller,具体代码与上例相同

    @Controller
    public class Test {
        @Autowired
        private DataSource datasource;
    
        @RequestMapping("/test")
        @ResponseBody
        public String test() throws Exception {
            Connection con = datasource.getConnection();
            // 拿到con就可以操作了
            return "spring mvc running";
        }
    }
    

    mybatis持久化框架

    mybatis轻量级,配置简单,使用方便,我们在tomcat pool基础上来配置,当然,使用tomcat pool配置只是为了得到dataSource,如果你用dbcp、c3p0等连接池,只要修改下这个dataSource的配置就好,mybatis本身的配置不用修改

    配置依赖

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.1</version>
    </dependency>
    

    我们定义一个TestDao.java接口,这就是mybatis要实现的东西

    package com.xmyself.dao;
    public interface TestDao {
        public String test();
    }
    

    src/main/resources目录建一个mapper目录,里面放一个TestDao.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="com.xmyself.dao.TestDao">
        <select id="test" resultType="java.lang.String">
            select "test"
        </select>
    </mapper>
    

    mybatis通过一个xml文件实现了TestDao.java接口,很显然,这个实现过程肯定要用到dataSource,接下来的配置就是将TestDao.java、TestDao.xml、dataSource三者关联起来,在spring的xml配置文件(哪个配置文件没关系,只要spring能加载)添加如下内容

    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/mysql" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath*:mapper/*.xml" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.xmyself.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    

    这个配置我其实有点疑惑,TestDao.xml中有对TestDao.java接口的声明,所以应该只需要将dataSource与TestDao.xml做关联就够了,但实际上我没有找到这种方式

    这时候启动工程,spring加载过程会报错,其实我是故意的,_

    Caused by: java.lang.ClassNotFoundException: org.mybatis.spring.SqlSessionFactoryBean
    

    因为spring内部没有直接对mybatis的支持,所以需要依赖中间层jar包,另外,还需要spring-jdbc提供对dao的支持

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>3.2.17.RELEASE</version>
    </dependency>
    

    我们整一个类来测试吧,还是以spring mvc为例,整一个controller

    @Controller
    public class Test {
        @Autowired
        private TestDao testDao;
    
        @RequestMapping("/test")
        @ResponseBody
        public String test() throws Exception {
            System.out.println(testDao.test());
            return "spring mvc running";
        }
    }
    

    浏览器访问 http://localhost:8080/springmvc/test就能看到后台输出“test”,mybatis配置完成

    redis缓存服务

    redis是一种key-value非关系型数据库,特点是运行于内存中,速度快,作为缓存服务器非常不错

    java对redis数据库的访问是通过jedis完成的

    配置依赖

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    

    初始化jedis连接,假设redis服务器地址为:192.168.253.128,端口:6379

    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="100" />
        <property name="maxTotal" value="300" />
        <property name="maxWaitMillis" value="1000" />
        <property name="testOnBorrow" value="true" />
    </bean>
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1" value="192.168.253.128" type="java.lang.String" />
        <constructor-arg index="2" value="6379" type="int" />
    </bean>
    

    这段代码放在哪没关系,只要spring能加载到,注意,构造器注入一定要指明type类型然后我们整一个类来测试,以spring mvc为例,整一个controller

    @Controller
    public class Test {
        @Autowired
        private JedisPool pool;
    
        @RequestMapping("/test")
        @ResponseBody
        public String test() {
            Jedis redis = pool.getResource();
            redis.set("test", "test");
            System.out.println(redis.get("test"));
            return "spring mvc running";
        }
    }
    

    浏览器访问 http://localhost:8080/springmvc/test,就能看到后台输出“test”,jedis配置完成

    dubbo分布式服务

    dubbo是阿里巴巴开源的分布式rpc框架,现在假设服务提供方正常工作,我们只配置在spring中使用dubbo服务

    配置依赖,假设dubbo使用zookeeper作为注册中心

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.5.3</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.101tec</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.4</version>
        <exclusions>
            <exclusion>
                <artifactId>org.apache.zookeeper</artifactId>
                <groupId>zookeeper</groupId>
            </exclusion>
            <exclusion>
                <artifactId>zookeeper</artifactId>
                <groupId>org.apache.zookeeper</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.9</version>
    </dependency>
    

    在src/main/resources的spring目录放一个dubbo-client.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:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd 
                            http://code.alibabatech.com/schema/dubbo 
                            http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <!-- 服务名称 -->
        <dubbo:application name="dubbo-demo" />
        <!-- 注册中心 -->
        <dubbo:registry protocol="zookeeper" address="172.17.210.124:2181" />
        <!-- 服务接口 -->
        <dubbo:reference id="demoService" interface="org.dubbo.demo.client.DemoService" version="0.0.1" />
    </beans>
      然后让spring加载dubbo-client.xml
    <import resource="classpath*:/spring/dubbo-client.xml" />
      启动工程,DemoService接口提供的方法就可以用了,就像调用本地方法一样
    @Controller
    public class Test{
        @Autowired
        private DemoService demoService;
    
        @RequestMapping("/test")
        @ResponseBody
        public String test() {
            return demoService.test("dubbo-demo-test");
        }
    }
    

    当然,服务使用者需要拿到服务提供者声明服务接口的jar,在公司内部,这通常也是一个依赖

    <dependency>
        <groupId>com.xmyself</groupId>
        <artifactId>dubbo-demo-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    

    相关文章

      网友评论

          本文标题:spring与spring mvc集成多种技术构建复杂工程

          本文链接:https://www.haomeiwen.com/subject/kixbvttx.html