一、Maven多模块项目的创建

    我们需要建立一个多模块的maven项目,其目录结构为

其中student-api用于暴露接口;student-service用语处理业务逻辑及调用数据访问对象,返回相应数据;student-web主要用于提供dubbo服务,及其他db、spring、springMVC、mybatis等配置。这样设计能够将业务逻辑与数据访问隔离开,同时贴合了spring目标之一,就是允许我们在开发应用的程序时,能够遵循面向对象(OO)原则中的“针对接口编程”,很大程度上达到松耦合。这里将接口API隔离出来作为dubbo生产者的服务接口,供消费应用调用(在后续详细讲解)。

    1.新建Maven项目


2.选择项目存放路径后,选择创建一个简单的maven项目
3.
 3.填写GroupId和ArtifactId,注意选择或者填写版本号
 
点击完成后,建立好了student-demo项目。之后删除项目src目录,打开pom.xml将<packaging>jar</packaging>修改为<packaging>pom</packaging>,pom表示它是一个被继承的模块。修改后的pom.xml如下
`<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"&gt;
<modelVersion>4.0.0</modelVersion>

<groupId>com.student.demo</groupId>
<artifactId>student-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>student-demo</name>
<url>http://maven.apache.org</url&gt;

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--模块建立好以后自动生成的-->
<modules>
<module>student-service</module>
<module>student-api</module>
<module>student-web</module>
</modules>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
`
在建成的项目student-demo上右键选择Maven Module后创建子项目student-api。

填写子模块名字:

项目类型选择:

 点击完成,建立好第一个模块后,同样的过程建立好student-service模块和student-web模块,需要注意的是student-web选择的maven类型是:

修改子模块项目目录中的pom.xml文件,把<groupId>XXX</groupId>和<version>1.0.0-SNAPSHOT</version>去掉,加上<packaging>jar</packaging>,因为groupId和version会继承student-demo中的groupId和version,packaging设置打包方式为jar。例如修改后的student-service模块的pom.xml如下:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0</modelVersion><parent><groupId>com.student.demo</groupId><artifactId>student-demo</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>student-service</artifactId><packaging>jar</packaging>
</project>

至此,maven多模块项目已经创建完成,现在我们需要在student-demo项目的pom中增加<dependencyManagement>标签定义可被子项目继承的第三方依赖包,打包配置,资源插件等,同时注意统一定义依赖的版本,避免冲突。这里还利用Maven配置了profiles,可根据情况增加不同的运行环境,并方便快捷地切换项目运行环境,目前我们只设置了dev开发环境。

<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.student.demo</groupId><artifactId>student-demo</artifactId><version>1.0.0-SNAPSHOT</version><packaging>pom</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><dep.ver.lombok>1.16.10</dep.ver.lombok><dep.ver.druid>1.0.1</dep.ver.druid><dep.ver.mysql>5.1.21</dep.ver.mysql><dep.ver.springframework>4.2.5.RELEASE</dep.ver.springframework><dep.ver.mybatis>3.3.0</dep.ver.mybatis><dep.ver.mybatis-spring>1.3.0</dep.ver.mybatis-spring><dep.ver.pagehelper>4.1.6</dep.ver.pagehelper><dep.ver.aspectjrt>1.5.4</dep.ver.aspectjrt><dep.ver.aspectjweaver>1.8.0</dep.ver.aspectjweaver><dep.ver.servlet>3.1.0</dep.ver.servlet><dep.ver.orika-core>1.4.6</dep.ver.orika-core><dep.ver.javassist>3.20.0-GA</dep.ver.javassist><dep.ver.paranamer>2.7</dep.ver.paranamer><dep.ver.concurrentlinkedhashmap-lru>1.4.2</dep.ver.concurrentlinkedhashmap-lru><dep.ver.gson>2.2.4</dep.ver.gson><dep.ver.guava>15.0</dep.ver.guava><dep.ver.slf4j>1.7.21</dep.ver.slf4j><dep.ver.logback>1.1.7</dep.ver.logback><dep.ver.log4j>1.2.12</dep.ver.log4j><dep.ver.slf4j-log4j12>1.7.5</dep.ver.slf4j-log4j12><dep.ver.logback-ext-spring>0.1.2</dep.ver.logback-ext-spring><dep.ver.dubbo>2.5.3</dep.ver.dubbo><dep.ver.zookeeper>3.4.8</dep.ver.zookeeper><dep.ver.zkclient>0.8</dep.ver.zkclient><dep.ver.commons-lang3>3.1</dep.ver.commons-lang3><dep.ver.jackson>1.9.12</dep.ver.jackson><dep.ver.shiro>1.2.3</dep.ver.shiro><dep.ver.freemarker>2.3.22</dep.ver.freemarker><dep.ver.commons-beanutils>1.9.2</dep.ver.commons-beanutils><dep.ver.junit>4.11</dep.ver.junit><dep.ver.mockito>1.10.19</dep.ver.mockito><dep.ver.joda-time>2.9.3</dep.ver.joda-time><dep.ver.commons-collections4>4.1</dep.ver.commons-collections4><dep.ver.httpclient>4.5.2</dep.ver.httpclient><dep.ver.fastjson>1.2.11</dep.ver.fastjson><plg.ver.maven-resources-plugin>2.7</plg.ver.maven-resources-plugin><plg.ver.maven-compiler-plugin>2.5.1</plg.ver.maven-compiler-plugin><plg.ver.maven-source-plugin>3.0.0</plg.ver.maven-source-plugin><plg.ver.lombok-maven-plugin>1.14.8.0</plg.ver.lombok-maven-plugin><jdk.ver>1.8</jdk.ver><encoding>UTF-8</encoding><center.project.name>${project.artifactId}</center.project.name><profiles.dir>src/profiles</profiles.dir><jackson.version>2.6.0</jackson.version></properties><modules><module>student-service</module><module>student-api</module><module>student-web</module></modules><dependencies><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.2.4.Final</version></dependency></dependencies><dependencyManagement><dependencies><!-- spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${dep.ver.springframework}</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${dep.ver.springframework}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${dep.ver.springframework}</version></dependency><!-- spring --><!-- db --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${dep.ver.druid}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${dep.ver.mysql}</version></dependency><!-- db --><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${dep.ver.mybatis}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${dep.ver.mybatis-spring}</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>${dep.ver.pagehelper}</version></dependency><!-- mybatis --><!-- apache --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${dep.ver.commons-lang3}</version></dependency><!-- apache --><!-- commons-beanutils --><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>${dep.ver.commons-beanutils}</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><!-- commons-beanutils --><!-- log --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${dep.ver.slf4j}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>log4j-over-slf4j</artifactId><version>${dep.ver.slf4j}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${dep.ver.slf4j}</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>${dep.ver.logback}</version></dependency><!-- log --><!-- dubbo --><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>${dep.ver.dubbo}</version><exclusions><exclusion><artifactId>spring</artifactId><groupId>org.springframework</groupId></exclusion><exclusion><artifactId>netty</artifactId><groupId>org.jboss.netty</groupId></exclusion></exclusions></dependency><!-- dubbo --><!-- zookeeper --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>${dep.ver.zookeeper}</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.101tec</groupId><artifactId>zkclient</artifactId><version>${dep.ver.zkclient}</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion></exclusions></dependency><!-- zookeeper --><!-- jackson --><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-core-asl</artifactId><version>${dep.ver.jackson}</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>${dep.ver.jackson}</version></dependency><!-- jackson --><!-- aspectj --><dependency><groupId>aspectj</groupId><artifactId>aspectjrt</artifactId><version>${dep.ver.aspectjrt}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${dep.ver.aspectjweaver}</version></dependency><!-- aspectj --><!-- servlet --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>${dep.ver.servlet}</version><scope>provided</scope></dependency><!-- servlet --><!-- javassist --><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>${dep.ver.javassist}</version></dependency><!-- javassist --><!-- test start --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${dep.ver.junit}</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${dep.ver.springframework}</version><scope>test</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>${dep.ver.mockito}</version><scope>test</scope></dependency><!-- test end --><!-- google --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>${dep.ver.gson}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${dep.ver.guava}</version></dependency><!-- google --><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${dep.ver.lombok}</version></dependency><!-- lombok --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>${dep.ver.commons-collections4}</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>${dep.ver.httpclient}</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency></dependencies></dependencyManagement><profiles><profile><id>local</id><build><resources><resource><directory>${profiles.dir}/local</directory></resource></resources></build></profile><profile><id>dev</id><build><resources><resource><directory>${profiles.dir}/dev</directory></resource></resources></build></profile></profiles><build><finalName>${center.project.name}</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>${plg.ver.maven-resources-plugin}</version><configuration><encoding>${encoding}</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${plg.ver.maven-compiler-plugin}</version><configuration><source>${jdk.ver}</source><target>${jdk.ver}</target><encoding>${encoding}</encoding></configuration></plugin><plugin><artifactId>maven-source-plugin</artifactId><version>${plg.ver.maven-source-plugin}</version><configuration><attach>true</attach></configuration> <executions><execution><phase>compile</phase><goals><goal>jar</goal></goals></execution></executions></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources></build>
</project>

在student-api中继承父pom的依赖,并且直接引入。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0</modelVersion><parent><groupId>com.student.demo</groupId><artifactId>student-demo</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>student-api</artifactId><dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${dep.ver.fastjson}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><!-- google --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency><!-- google --></dependencies>
</project>

在student-service中添加继承依赖,添加对student-api的依赖。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0</modelVersion><parent><groupId>com.student.demo</groupId><artifactId>student-demo</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>student-service</artifactId><dependencies><dependency><groupId>com.student.demo</groupId><artifactId>student-api</artifactId><version>1.0.0-SNAPSHOT</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${dep.ver.fastjson}</version></dependency><!-- oss相关依赖 --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>2.0.7</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><!-- oss相关依赖 结束 --><!-- db --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- db --><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId></dependency><!-- mybatis --><!-- spring配置 --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></dependency><!-- spring配置 --><!-- jackson --><!-- <dependency> --><!-- <groupId>org.codehaus.jackson</groupId> --><!-- <artifactId>jackson-core-asl</artifactId> --><!-- </dependency> --><!-- <dependency> --><!-- <groupId>org.codehaus.jackson</groupId> --><!-- <artifactId>jackson-mapper-asl</artifactId> --><!-- </dependency> --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>${jackson.version}</version></dependency><!-- jackson --><!-- log --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId></dependency><dependency><groupId>org.slf4j</groupId><artifactId>log4j-over-slf4j</artifactId></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId></dependency><!-- log --><!-- google --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency><!-- <dependency> --><!-- <groupId>com.google.code.gson</groupId> --><!-- <artifactId>gson</artifactId> --><!-- </dependency> --><!-- google --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId></dependency><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId></dependency><!-- aspectj --><dependency><groupId>aspectj</groupId><artifactId>aspectjrt</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency><!-- aspectj --><!-- dubbo --><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><exclusions><exclusion><artifactId>spring</artifactId><groupId>org.springframework</groupId></exclusion><exclusion><artifactId>netty</artifactId><groupId>org.jboss.netty</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.101tec</groupId><artifactId>zkclient</artifactId><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><!-- dubbo --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.1</version></dependency></dependencies>
</project>

在student-web中继承依赖,添加对student-api,student-service的依赖。注意子项目依赖版本都为<version>1.0.0-SNAPSHOT</version>

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0</modelVersion><parent><groupId>com.student.demo</groupId><artifactId>student-demo</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>student-web</artifactId><packaging>war</packaging><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>com.student.demo</groupId><artifactId>student-api</artifactId><version>1.0.0-SNAPSHOT</version></dependency><dependency><groupId>com.student.demo</groupId><artifactId>student-service</artifactId><version>1.0.0-SNAPSHOT</version></dependency></dependencies><build><finalName>student-web</finalName></build>
</project>

 ```
二、Maven与SpringMVC的整合

    1.第一部分已经在项目pom文件中配置了spring的相关依赖

    2.在student-web项目根路径上添加profiles源目录及配置文件

     注意是建立源文件不是普通文件夹。

  然后在此源文件夹下建立普通文件夹props,用于存放配置文件。在props下新建db-config.properties资源文件,用于配置mysql,其配置内容为:

1 database.database=mysql
2 database.driverClassName=com.mysql.jdbc.Driver
3 database.url=jdbc:mysql://172.0.0.1:3306/student_data?characterEncoding=utf8
4 database.user=root
5 database.password=root
6 database.show_sql=true

在mysql数据库中建立一张简单的student数据表,其结构为:

3.在student-web的src/main/resources目录中新建spring文件夹,新建spring-base.xml和spring-dispatcher.xml。其中值得说明一下的是,spring监听器ContextLoaderListener和控制器DispatcherServlet会加载应用上下文。其中上下文参数contextConfigLocation的value值是根应用上下文路径classpath:spring/spring-base.xml,它会被ContextLoaderListener加载bean定义。spring-base.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- 开启aspectj自动注解 --><aop:aspectj-autoproxy proxy-target-class="true" /><context:component-scan base-package="org.student" /><context:annotation-config /><!-- 配置文件加载 --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="order" value="1" /><property name="ignoreUnresolvablePlaceholders" value="true" /><property name="locations"><list><value>classpath:props/db-config.properties</value></list></property></bean><import resource="classpath:spring/spring-db.xml" />
</beans>

  同样DispatcherServlet会从classpath:spring/spring-dispatcher.xml加载它的bean。

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter " /></mvc:message-converters></mvc:annotation-driven><bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /><!-- 相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个bean,配置一些messageconverter。即解决了@Controller注解的使用前提配置 -->
</beans>

 4.在Web.xml中声明DispatcherServlet

  SpringMVC所有请求都会通过一个前端控制器DispatcherServlet,通过这个控制器将请求委托给应用程序的其它执行单元来处理,所以需要通过web.xml来注册。打开student-web项目目录下src/main/webapp/WEB-INF/web.xml,修改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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="schedule-console" version="3.0">
<display-name>student-web</display-name>

<!-- web.xml中加载顺序是 context-param -> listener -> filter -> servlet -->
<!-- spring基础配置文件位置 -->
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-base.xml</param-value>
</context-param><!-- Spring监听 -->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 设置servlet编码开始 -->
<filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 设置servlet编码结束 -->
<servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-dispatcher.xml</param-value></init-param>
</servlet>
<servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>
`
 5.spring与Mybatis的整合

     在student-web的src/main/resources目录中新建mybatis文件夹,再在此目录新建mybatis.xml和mapper文件夹。在spring文件夹下新建spring-db.xml用于spring加载mybatis配置。spring-db.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"><!-- 采用druid作为连接池 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close"><!-- 基本属性 url、user、password --><property name="driverClassName" value="${database.driverClassName}" /><property name="url" value="${database.url}" /><property name="username" value="${database.user}" /><property name="password" value="${database.password}" /><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="1" /><property name="minIdle" value="1" /><property name="maxActive" value="20" /><!-- 配置获取连接等待超时的时间 --><property name="maxWait" value="60000" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000" /><property name="validationQuery" value="SELECT 'x'" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize"value="20" /><!-- 配置监控统计拦截的filters --><property name="filters" value="stat" /></bean><!-- 配置mybatis的sqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="configLocation" value="classpath:mybatis/mybatis.xml" /><property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" /></bean><!-- mybatis mapper接口扫描 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="org.student.service.mapper" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- 开启@Transactional事务注解 --><tx:annotation-driven transaction-manager="transactionManager" />
</beans>

 三、Dubbo的环境配置及与整合

     我们已经搭建好student-demo项目来作为provider,为其它服务提供接口,所以我们需要先配置好dubbo提供者,PS:这里不会讲解zookeeper的搭建,请自行百度。其项目结构为:

     1.首先在student-web中配置dubbo

  由于我们已经在student-demo中添加了dubbo和zookeeper的相关依赖,下一步字啊resources目录中建立dubbo文件夹,再新建dubbo-producer.xml,同时在profiles的dev环境中添加dubbo-producer.properties配置文件,设置zookeeper注册中心暴露服务地址,配置group分组,服务端口,注册中心请求超时时间(毫秒)和版本。其中组别+接口地址+版本号唯一的标识了一个接口。文件内容为:

1 student-registry-address=172.0.0.1:2181
2 student-group=student-min
3 student-service-port=22026
4 student-timeout=120000
5 student-version=1.0.0

这样我们就可以来配置dubbo-producer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><context:property-placeholder location="classpath:props/dubbo-producer.properties" ignore-unresolvable="true"/><dubbo:application name="provider-student-demo"/><dubbo:registry address="${student-registry-address}" protocol="zookeeper"/><dubbo:protocol name="dubbo" port="${student-service-port}" accesslog="true" />
</beans>

2.写一个简单的服务接口
1)首先在student-service中建立Student实体类

package org.student.bean;public class Student {private Long id;private String name;private Integer age;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}

 2)同时在student-api中建立与实体bean对应的DTO类实现Serializable接口,并重写toString方法。一般为了不破坏实体类和数据库表一一对应的接口,我们会新建一个DTO实体类,并且加入一些冗余的字段,作为前后端的传输对象。
`package org.student.api.dto;

import java.io.Serializable;

public class StudentDTO implements Serializable{

private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Integer age;
public Long getId() {return id;
}
public void setId(Long id) {this.id = id;
}
public String getName() {return name;
}
public void setName(String name) {this.name = name;
}
public Integer getAge() {return age;
}
public void setAge(Integer age) {this.age = age;
}@Override
public String toString() {return "id = " + id + ", name = " + name + ",age = " + age;
}

}
`
3)在student-api中建立StudentApi接口,值得注意的是@service注解中的对象

package org.student.api;import java.util.List;import org.student.api.dto.StudentDTO;public interface StudentApi {List<StudentDTO> listStudents();
}

4)在dubbo-producer.xml中注册StudentApi,添加配置:

<dubbo:service interface="org.student.api.StudentApi" ref="studentApi"   group="${student-group}" version="${student-version}" timeout="${student-timeout}" />

5)从service业务逻辑层子模块开始编写接口实现,新建在student-service中新建StudentBiz实现StudentApi接口

package org.student.service.biz;import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.student.api.StudentApi;
import org.student.api.dto.StudentDTO;
import org.student.bean.Student;
import org.student.service.StudentService;import com.google.common.collect.Lists;@Service("studentApi")
public class StudentBiz implements StudentApi{private Logger logger = LoggerFactory.getLogger(StudentBiz.class);@Autowiredprivate StudentService studentService;@Overridepublic List<StudentDTO> listStudents() {List<Student> listStudent = studentService.listStudent();List<StudentDTO> listStudentDTO = Lists.newArrayList();for(Student student: listStudent){StudentDTO studentDTO = new StudentDTO();studentDTO.setId(student.getId());studentDTO.setAge(student.getAge());studentDTO.setName(student.getName());listStudentDTO.add(studentDTO);}return listStudentDTO;}
}

6)在student-service中创建service层接口StudentService

package org.student.service;import java.util.List;import org.springframework.stereotype.Service;
import org.student.bean.Student;@Service
public interface StudentService {List<Student> listStudent();}

7)在student-service中实现StudentService接口

package org.student.service.impl;import java.util.List;import javax.annotation.Resource;import org.springframework.stereotype.Service;
import org.student.bean.Student;
import org.student.service.StudentService;
import org.student.service.mapper.StudentMapper;@Service("studentService")
public class StudentServiceImpl implements StudentService{@Resourceprivate StudentMapper studentMapper;@Overridepublic List<Student> listStudent() {List<Student> listStudent = studentMapper.listStudent();return listStudent;}}

8)在student-service中创建数据层StudentMapper接口

package org.student.service.mapper;import java.util.List;import org.student.bean.Student;public interface StudentMapper {List<Student> listStudent();
}

9)在student-web中创建实体映射的XML文件,注意StudentMapper类与sql ID的对应关系

<?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="org.student.service.mapper.StudentMapper"><!--查询字段--><sql id="columns">a.id,a.name,a.age</sql><!--查询结果集--><resultMap id="beanMap" type="org.student.bean.Student"><result property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/></resultMap><!--根据主键获取实体--><select id="listStudent" resultMap="beanMap">SELECT<include refid="columns"/>FROMstudent a</select></mapper>

dubbo提供者已创建完成,创建完成子应用结构为



1)dubbo-consumer.properties的service-group应该与提供者一致,否者找不到提供者方的接口。

同时pom.xml中需要增加对的依赖

<dependency><groupId>com.student.demo</groupId><artifactId>student-api</artifactId><version>1.0.0-SNAPSHOT</version>
</dependency>
student-registry-address=172.0.0.1:2181
student-service-group=student-min
student-service-version=1.0.0
student-service-timeout=120000

2)spring-dubbo-consumer.xml的配置及接口调用方式
`<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;

<dubbo:application name="consumer-student-test" /><dubbo:registry address="${student-registry-address}" protocol="zookeeper" /><dubbo:reference id="studentApi" interface="org.student.api.StudentApi"group="${student-service-group}" version="${student-service-version}"check="false" />

</beans>
`
3)调用者的controller层 

package org.student.controller;import javax.annotation.Resource;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.student.api.StudentApi;@RestController
@RequestMapping("/student")
public class StudentController {private static Logger logger = LoggerFactory.getLogger(StudentController.class);@Resourceprivate StudentApi studentApi;@RequestMapping(path = "/listStudent", method = RequestMethod.POST)public void listStudent(){logger.info("get students...");logger.info("the data are " + studentApi.listStudents());}
}

4)服务器同时启动provider和consumer,会看到启动信息

<span style="white-space:pre">  </span>查看zookeeper注册中心发现提供者消费者都已成功注册
<span style="white-space:pre">  </span><img src="https://img-blog.csdn.net/20161110162252922?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="800" height="30" alt="" />
<span style="white-space:pre">  </span><img src="https://img-blog.csdn.net/20161110162424347?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="800" height="90" alt="" />

 5)测试接口
    由于我并没有写view层来展示数据,现在只能通过控制台的日志信息来简单测试接口。(logback的用法不做解释)利用浏览器post请求访问<br/>http://172.0.0.1:8080/student-test/student/listStudent,控制台输出为<br/>

[http-nio-8080-exec-2] INFO  2016-11-07 18:33:24.450 o.s.c.StudentController[24] - get students...
[DubboServerHandler-172.28.19.7:22026-thread-2] INFO  2016-11-07 18:33:24.729 d.a.o.s.a.StudentApi[58] -  [DUBBO] [2016-11-07 18:3:24] 172.28.19.7:56346 -> 172.28.19.7:22026 - student-min/org.student.api.StudentApi:1.0.0 listStudents() , dubbo version: 2.5.3, current host: 127.0.0.1
[http-nio-8080-exec-2] INFO  2016-11-07 18:33:25.026 o.s.c.StudentController[25] - the data are [id = 1, name = 张三,age = 20]

四、新手在整合过程易犯的错误。

  1.ClassNotFound异常
  严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener<br/>java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener<br/>at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)<br/>at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166)<br/>at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:518)<br/>at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:499)<br/>at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)<br/>at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4764)<br/>at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)<br/>at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)<br/>at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)<br/>at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)<br/>at java.util.concurrent.FutureTask.run(FutureTask.java:266)<br/>at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)<br/>at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)<br/>at java.lang.Thread.run(Thread.java:745)<br/>
eclipse会自动将deployment assembly指定的工程,打成jar包,放入到web-inf/lib目录下,tomcat在发布项目的时候没有同时发布maven依赖所添加的jar包,但是如果在deployment assembly没有配置相应的依赖包,就会抛出异常。解决方法:项目 —> properties
-> Deployment Assembly -> Add -> Java Build Path Entries -> 选择Maven Dependencies -> Finish -> OK 把对应的Maven依赖包也发布到tomcat,调试时会自动把那些jar发布到指定目录下,tomcat也能找到那些jar了。

    另外,同样的报错可能由于不同的原因造成,如果没有激活Maven profile也会报这种错误,激活profile的方式有很多,通过命令首先需要在pom.xml中用<profiles>配置(详细配置请查看上文)再通过命令行:
mvn install -Pdev #激活dev环境
也可以通过eclipse的配置:项目-->properties-->Maven-->填写profile名-->apply-->finish

2.启动student-web,spring创建bean对象失败
十一月 07, 2016 8:19:24 下午 org.apache.catalina.core.StandardContext listenerStart
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.student.api.StudentApi': Cannot resolve reference to bean 'studentApi' while setting bean property 'ref'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'studentApi' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
  ...
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
 ...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'studentApi' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
...
 spring有强大的注解帮助我们简化很大部分代码,并降低的耦合。@Autowired或@Resource在 Bean 类中使用自动注入功能,但是 Bean 还是在 XML 文件中通过 <bean>
进行定义 —— 也就是说,在 XML 配置文件中定义 Bean,通过@Autowired或@Resource为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。以前通过在spring文件中配置<bean>的方式被移除,仅需要添加一行 <context:component-scan/> 配置就解决所有问题了——Spring XML 配置文件得到了极致的简化。<context:component-scan/> 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。解决:在spring-base.xml中添加
&lt;context:component-scan base-package="org.student" /&gt;
3.消费者访问dubbo接口被拒绝
严重: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.dubbo.rpc.RpcException: Forbid consumer 172.0.0.1 access service org.student.api.StudentApi from registry 172.0.0.1:2181 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist).] with root cause<br/>com.alibaba.dubbo.rpc.RpcException: Forbid consumer 172.0.0.1 access service org.student.api.StudentApi from registry 172.0.0.1:2181 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist). at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:579) at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:73) at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:260) at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:219) at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:72) at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52) at com.alibaba.dubbo.common.bytecode.proxy0.listStudents(proxy0.java) at org.student.controller.StudentController.listStudent(StudentController.java:25) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498)<br/>....<br/>
如果消费者访问的接口路径不正确,则无法调用接口。出现这种错误是我没有把消费者的组设置成提供者的组,解决方法是group保持一致

4.访问所有接口都报404错误

INFO  2016-11-08 12:42:28.507 o.s.w.s.DispatcherServlet[488] - FrameworkServlet 'dispatcher': initialization started
INFO  2016-11-08 12:42:28.518 o.s.w.c.s.XmlWebApplicationContext[578] - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Tue Nov 08 12:42:28 CST 2016]; parent: Root WebApplicationContext
INFO  2016-11-08 12:42:28.519 o.s.b.f.x.XmlBeanDefinitionReader[317] - Loading XML bean definitions from class path resource [spring/spring-dispatcher.xml]
INFO  2016-11-08 12:42:28.657 o.s.b.f.s.DefaultListableBeanFactory[839] - Overriding bean definition for bean 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping' with a different definition: replacing [Root bean: class [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Root bean: class [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
...
INFO  2016-11-08 12:42:29.545 o.s.w.s.m.m.a.RequestMappingHandlerAdapter[532] - Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Tue Nov 08 12:42:28 CST 2016]; parent: Root WebApplicationContext
INFO  2016-11-08 12:42:29.810 o.s.w.s.v.v.VelocityConfigurer[140] - ClasspathResourceLoader with name 'springMacro' added to configured VelocityEngine
INFO  2016-11-08 12:42:30.193 o.s.w.s.DispatcherServlet[507] - FrameworkServlet 'dispatcher': initialization completed in 1684 ms
WARN  2016-11-08 12:42:30.206 o.s.w.s.PageNotFound[1136] - No mapping found for HTTP request with URI [/student/listStudent] in DispatcherServlet with name 'dispatcher'

 这个错误我找了很久才发现,并不是简单的访问路径错误。仔细查看日志信息会发现spring加载dispatcher的过程,截取在web.xml中配置
`<!--spring加载-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-base.xml</param-value>
</context-param>
...

<!--springMVC加载-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-dispatcher.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

`
 在Tomcat启动时,web.xml中加载顺序是 context-param -> listener -> filter -> servlet,ContextLoaderListener基于Web上下文级别的监听器在启动服务器时就创建ApplicationContext并且将配置的Spring Bean加载到XML中。DispatcherServlet是一个请求分发控制器,所有匹配的URL都会通过该Servlet分发执行,在创建Servlet对象时会初始化Spring
MVC相关配置。spring-dispatcher.xml中定义了控制器映射,使用Controller+RequestMapping注解映射时,相关controller组件扫描要定义在spring-dispatcher.xml中,而非spring-base.xml中。依据这样的分析,我去查看了student-test项目中spring-dispatcher.xml和spring-base.xml的配置,发现spring-base.xml配置了

<context:component-scan base-package="org.student"/>

而在spring-dispatcher.xml中未配置扫描路径。所以spring无法加载controller中的映射,自然会404了,解决方式则是在spring-dispatcher.xml中加上扫描。

欢迎工作一到五年的Java工程师朋友们加入Java架构开发:855801563

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

转载于:https://blog.51cto.com/13981400/2293965

Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出...相关推荐

  1. 前后端分离项目全环境搭建(Ruoyi框架)

    记录一下在全新的电脑上搭建前后端分离项目的全过程,方便下次继续Copy.(以Ruoyi框架为例子进行操作) 目录 前端 1.VsCode 2.NodeJs 后端 JDK idea Tomcat Mav ...

  2. myBatis-plus实现先按条件查询,再把查询结果分页(基于xboot框架的前后端分离项目的一部分)

    一.数据库 业务需求:查询数据库表test_point(里面有十个温度测试点,不同测试点有不同时间的测试温度),要把十个点的各自最新时间的数据拿到,再分页展示到页面上. sql文件: /* SQLyo ...

  3. dubbo分布式服务框架(高级特性篇)

    目录 1.序列化 2.地址缓存 3.超时 4.重试 5.多版本 6.负载均衡 7.集群容错 8.服务降级 本文参考b站黑马程序员dubbo入门课程 视频连接:黑马程序员Dubbo快速入门,Java分布 ...

  4. 首个直播商城,拼团商城,小程序商城的微服务分布式框架,前后端分离

    简介: sdb mall 项目说明 sdb是一个轻量级的在renren-fast基础上利用jfinal架构二次开发的一个极速二次开发直播,拼团商城框架,前后端分离的Java快速开发平台,C端采用微信小 ...

  5. 【两万字图文详解】 运动会管理系统-前后端分离-项目开发:【后端】SpringBoot, SpringMVC, MyBatis【前端】Vue.js,ElementUI

    项目名称:运动会管理系统  技术栈:      后端:SpringBoot,SpringMVC,MyBatis,tkmapper,Maven聚合工程等      前端:Vue.js,Element-u ...

  6. vue和Java做数据交互_基于vue和springmvc前后端分离,json类接口调用介绍

    基于vue和springmvc前后端分离,json类接口调用介绍 版本要求:spring-3.2.9.RELEASE.vue-2.9.2.axios-0.17.1,其中axios作为http clie ...

  7. SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【后端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】

    前后端分离项目快速搭建[后端篇] 数据库准备 后端搭建 1.快速创建个SpringBoot项目 2.引入依赖 3.编写代码快速生成代码 4.运行代码生成器生成代码 5.编写application.pr ...

  8. crm开源系统 tp框架_八个开源的 Spring Boot 前后端分离项目,一定要收藏!

    点击蓝色字关注我们 前后端分离已经在慢慢走进各公司的技术栈,不少公司都已经切换到这个技术栈上面了.即使贵司目前没有切换到这个技术栈上面,也非常建议大家学习一下前后端分离开发,以免在公司干了两三年,SS ...

  9. 基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台、多租户

    基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台.多租户.支持MySQL/SQLServer/ ...

  10. SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【前端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】

    前后端分离项目快速搭建[前端篇] 后端篇 前端篇 创建vue项目 安装所需工具 开始编码 1.在根目录下添加vue.config.js文件 2.编写main.js 3.编写App.vue 4.编写ax ...

最新文章

  1. 【分布式事务】面试官问我:MySQL中的XA事务崩溃了如何恢复??
  2. idea缩写快捷键_idea快捷键大全
  3. 算法------------搜索二维矩阵
  4. docker 安装mysql
  5. Vista新特征(Features)(英文)
  6. java 脚手架_肝了一个半月的 Java 项目快速开发脚手架:Chewing
  7. 光子计算机玩游戏,用于光计算的光子计算机
  8. java build返回空值_OKHTTP拦截器不断返回空值并使应用程序崩溃
  9. angularjs项目的页面跳转如何实现
  10. 去除Android 6.0 界面下的导航栏:NavigationBar
  11. php快速排序分割两部分,php四大算法|冒泡排序|快速排序|二分查找
  12. Android Studio报错:This Gradle plugin requires a newer IDE able to request IDE model level 3
  13. PostgreSQ 存储过程 和 存储函数的区别
  14. 路由器和带宽猫、AP、AC、交换机
  15. VC打印机使用 win95环境的下例子测试
  16. 树莓派Pico开发版
  17. php户型图识别,户型图上的那些标注都是啥?看不懂难怪被坑
  18. 1183: 【入门】判断能否构成三角形
  19. Python+Cplex学习笔记(三)—— docplex官方示例之营养膳食选择
  20. XXE漏洞以及Blind XXE总结

热门文章

  1. [Java] 蓝桥杯 BASIC-10 基础练习 十进制转十六进制
  2. 【Objective-C】栈(stack)和堆(heap)的区别
  3. L2-004. 这是二叉搜索树吗?-PAT团体程序设计天梯赛GPLT
  4. python检测端口是否被侦听
  5. linux下的tuxedo开发实例
  6. tmadmin: command not found和tmadmin: error while loading shared libraries: libgpnet.so
  7. ibatis sql_Map中出现异常:Cause: java.lang.RuntimeException: JavaBeansDataExchange could not instantiate..
  8. 通过java程序实现mysql 批量一个表的子段更新另一个表的字段
  9. 蒸妙集团用科学熏蒸法,弥补现代人在运动上的缺乏
  10. 洛谷P1962 斐波那契数列