Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题...
现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建。通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础。
首先说一下这篇文章的主要内容分为:
1、Maven多模块项目的创建;
2、Maven与SpringMVC的整合;
3、Dubbo的环境配置及与整合;
4、新手在整合过程易犯的错误。
通过一个简单的demo来说明,大家多多指教,分享经验!
一、Maven多模块项目的创建
我们需要建立一个多模块的maven项目,其目录结构为
其中student-api用于暴露接口;student-service用语处理业务逻辑及调用数据访问对象,返回相应数据;student-web主要用于提供dubbo服务,及其他db、spring、springMVC、mybatis等配置。这样设计能够将业务逻辑与数据访问隔离开,同时贴合了spring目标之一,就是允许我们在开发应用的程序时,能够遵循面向对象(OO)原则中的“针对接口编程”,很大程度上达到松耦合。这里将接口API隔离出来作为dubbo生产者的服务接口,供消费应用调用(在后续详细讲解)。
1.新建Maven项目
2.选择项目存放路径后,选择创建一个简单的maven项目
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"><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><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如下:
1 <?xml version="1.0"?> 2 <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" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>com.student.demo</groupId> 7 <artifactId>student-demo</artifactId> 8 <version>1.0.0-SNAPSHOT</version> 9 </parent> 10 11 <artifactId>student-service</artifactId> 12 <packaging>jar</packaging> 13 </project>
至此,maven多模块项目已经创建完成,现在我们需要在student-demo项目的pom中增加<dependencyManagement>标签定义可被子项目继承的第三方依赖包,打包配置,资源插件等,同时注意统一定义依赖的版本,避免冲突。这里还利用Maven配置了profiles,可根据情况增加不同的运行环境,并方便快捷地切换项目运行环境,目前我们只设置了dev开发环境。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 5 <groupId>com.student.demo</groupId> 6 <artifactId>student-demo</artifactId> 7 <version>1.0.0-SNAPSHOT</version> 8 <packaging>pom</packaging> 9 10 <properties> 11 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 12 <dep.ver.lombok>1.16.10</dep.ver.lombok> 13 <dep.ver.druid>1.0.1</dep.ver.druid> 14 <dep.ver.mysql>5.1.21</dep.ver.mysql> 15 <dep.ver.springframework>4.2.5.RELEASE</dep.ver.springframework> 16 <dep.ver.mybatis>3.3.0</dep.ver.mybatis> 17 <dep.ver.mybatis-spring>1.3.0</dep.ver.mybatis-spring> 18 <dep.ver.pagehelper>4.1.6</dep.ver.pagehelper> 19 <dep.ver.aspectjrt>1.5.4</dep.ver.aspectjrt> 20 <dep.ver.aspectjweaver>1.8.0</dep.ver.aspectjweaver> 21 <dep.ver.servlet>3.1.0</dep.ver.servlet> 22 <dep.ver.orika-core>1.4.6</dep.ver.orika-core> 23 <dep.ver.javassist>3.20.0-GA</dep.ver.javassist> 24 <dep.ver.paranamer>2.7</dep.ver.paranamer> 25 <dep.ver.concurrentlinkedhashmap-lru>1.4.2</dep.ver.concurrentlinkedhashmap-lru> 26 <dep.ver.gson>2.2.4</dep.ver.gson> 27 <dep.ver.guava>15.0</dep.ver.guava> 28 <dep.ver.slf4j>1.7.21</dep.ver.slf4j> 29 <dep.ver.logback>1.1.7</dep.ver.logback> 30 <dep.ver.log4j>1.2.12</dep.ver.log4j> 31 <dep.ver.slf4j-log4j12>1.7.5</dep.ver.slf4j-log4j12> 32 <dep.ver.logback-ext-spring>0.1.2</dep.ver.logback-ext-spring> 33 <dep.ver.dubbo>2.5.3</dep.ver.dubbo> 34 <dep.ver.zookeeper>3.4.8</dep.ver.zookeeper> 35 <dep.ver.zkclient>0.8</dep.ver.zkclient> 36 <dep.ver.commons-lang3>3.1</dep.ver.commons-lang3> 37 <dep.ver.jackson>1.9.12</dep.ver.jackson> 38 <dep.ver.shiro>1.2.3</dep.ver.shiro> 39 <dep.ver.freemarker>2.3.22</dep.ver.freemarker> 40 <dep.ver.commons-beanutils>1.9.2</dep.ver.commons-beanutils> 41 <dep.ver.junit>4.11</dep.ver.junit> 42 <dep.ver.mockito>1.10.19</dep.ver.mockito> 43 <dep.ver.joda-time>2.9.3</dep.ver.joda-time> 44 <dep.ver.commons-collections4>4.1</dep.ver.commons-collections4> 45 <dep.ver.httpclient>4.5.2</dep.ver.httpclient> 46 47 <dep.ver.fastjson>1.2.11</dep.ver.fastjson> 48 49 <plg.ver.maven-resources-plugin>2.7</plg.ver.maven-resources-plugin> 50 <plg.ver.maven-compiler-plugin>2.5.1</plg.ver.maven-compiler-plugin> 51 <plg.ver.maven-source-plugin>3.0.0</plg.ver.maven-source-plugin> 52 <plg.ver.lombok-maven-plugin>1.14.8.0</plg.ver.lombok-maven-plugin> 53 54 <jdk.ver>1.8</jdk.ver> 55 <encoding>UTF-8</encoding> 56 <center.project.name>${project.artifactId}</center.project.name> 57 <profiles.dir>src/profiles</profiles.dir> 58 <jackson.version>2.6.0</jackson.version> 59 </properties> 60 <modules> 61 <module>student-service</module> 62 <module>student-api</module> 63 <module>student-web</module> 64 </modules> 65 66 <dependencies> 67 <dependency> 68 <groupId>org.hibernate</groupId> 69 <artifactId>hibernate-validator</artifactId> 70 <version>5.2.4.Final</version> 71 </dependency> 72 </dependencies> 73 74 <dependencyManagement> 75 <dependencies> 76 <!-- spring --> 77 <dependency> 78 <groupId>org.springframework</groupId> 79 <artifactId>spring-core</artifactId> 80 <version>${dep.ver.springframework}</version> 81 <exclusions> 82 <exclusion> 83 <groupId>commons-logging</groupId> 84 <artifactId>commons-logging</artifactId> 85 </exclusion> 86 </exclusions> 87 </dependency> 88 <dependency> 89 <groupId>org.springframework</groupId> 90 <artifactId>spring-context</artifactId> 91 <version>${dep.ver.springframework}</version> 92 </dependency> 93 <dependency> 94 <groupId>org.springframework</groupId> 95 <artifactId>spring-context-support</artifactId> 96 <version>${dep.ver.springframework}</version> 97 </dependency> 98 <dependency> 99 <groupId>org.springframework</groupId> 100 <artifactId>spring-web</artifactId> 101 <version>${dep.ver.springframework}</version> 102 </dependency> 103 <dependency> 104 <groupId>org.springframework</groupId> 105 <artifactId>spring-webmvc</artifactId> 106 <version>${dep.ver.springframework}</version> 107 </dependency> 108 <dependency> 109 <groupId>org.springframework</groupId> 110 <artifactId>spring-jdbc</artifactId> 111 <version>${dep.ver.springframework}</version> 112 </dependency> 113 <dependency> 114 <groupId>org.springframework</groupId> 115 <artifactId>spring-tx</artifactId> 116 <version>${dep.ver.springframework}</version> 117 </dependency> 118 <dependency> 119 <groupId>org.springframework</groupId> 120 <artifactId>spring-aspects</artifactId> 121 <version>${dep.ver.springframework}</version> 122 </dependency> 123 <!-- spring --> 124 <!-- db --> 125 <dependency> 126 <groupId>com.alibaba</groupId> 127 <artifactId>druid</artifactId> 128 <version>${dep.ver.druid}</version> 129 </dependency> 130 <dependency> 131 <groupId>mysql</groupId> 132 <artifactId>mysql-connector-java</artifactId> 133 <version>${dep.ver.mysql}</version> 134 </dependency> 135 <!-- db --> 136 <!-- mybatis --> 137 <dependency> 138 <groupId>org.mybatis</groupId> 139 <artifactId>mybatis</artifactId> 140 <version>${dep.ver.mybatis}</version> 141 </dependency> 142 <dependency> 143 <groupId>org.mybatis</groupId> 144 <artifactId>mybatis-spring</artifactId> 145 <version>${dep.ver.mybatis-spring}</version> 146 </dependency> 147 <dependency> 148 <groupId>com.github.pagehelper</groupId> 149 <artifactId>pagehelper</artifactId> 150 <version>${dep.ver.pagehelper}</version> 151 </dependency> 152 <!-- mybatis --> 153 <!-- apache --> 154 <dependency> 155 <groupId>org.apache.commons</groupId> 156 <artifactId>commons-lang3</artifactId> 157 <version>${dep.ver.commons-lang3}</version> 158 </dependency> 159 <!-- apache --> 160 <!-- commons-beanutils --> 161 <dependency> 162 <groupId>commons-beanutils</groupId> 163 <artifactId>commons-beanutils</artifactId> 164 <version>${dep.ver.commons-beanutils}</version> 165 <exclusions> 166 <exclusion> 167 <groupId>commons-logging</groupId> 168 <artifactId>commons-logging</artifactId> 169 </exclusion> 170 </exclusions> 171 </dependency> 172 <!-- commons-beanutils --> 173 <!-- log --> 174 <dependency> 175 <groupId>org.slf4j</groupId> 176 <artifactId>slf4j-api</artifactId> 177 <version>${dep.ver.slf4j}</version> 178 </dependency> 179 <dependency> 180 <groupId>org.slf4j</groupId> 181 <artifactId>log4j-over-slf4j</artifactId> 182 <version>${dep.ver.slf4j}</version> 183 </dependency> 184 <dependency> 185 <groupId>org.slf4j</groupId> 186 <artifactId>jcl-over-slf4j</artifactId> 187 <version>${dep.ver.slf4j}</version> 188 </dependency> 189 <dependency> 190 <groupId>ch.qos.logback</groupId> 191 <artifactId>logback-classic</artifactId> 192 <version>${dep.ver.logback}</version> 193 </dependency> 194 <!-- log --> 195 <!-- dubbo --> 196 <dependency> 197 <groupId>com.alibaba</groupId> 198 <artifactId>dubbo</artifactId> 199 <version>${dep.ver.dubbo}</version> 200 <exclusions> 201 <exclusion> 202 <artifactId>spring</artifactId> 203 <groupId>org.springframework</groupId> 204 </exclusion> 205 <exclusion> 206 <artifactId>netty</artifactId> 207 <groupId>org.jboss.netty</groupId> 208 </exclusion> 209 </exclusions> 210 </dependency> 211 <!-- dubbo --> 212 <!-- zookeeper --> 213 <dependency> 214 <groupId>org.apache.zookeeper</groupId> 215 <artifactId>zookeeper</artifactId> 216 <version>${dep.ver.zookeeper}</version> 217 <exclusions> 218 <exclusion> 219 <groupId>log4j</groupId> 220 <artifactId>log4j</artifactId> 221 </exclusion> 222 </exclusions> 223 </dependency> 224 <dependency> 225 <groupId>com.101tec</groupId> 226 <artifactId>zkclient</artifactId> 227 <version>${dep.ver.zkclient}</version> 228 <exclusions> 229 <exclusion> 230 <groupId>log4j</groupId> 231 <artifactId>log4j</artifactId> 232 </exclusion> 233 </exclusions> 234 </dependency> 235 <!-- zookeeper --> 236 <!-- jackson --> 237 <dependency> 238 <groupId>org.codehaus.jackson</groupId> 239 <artifactId>jackson-core-asl</artifactId> 240 <version>${dep.ver.jackson}</version> 241 </dependency> 242 <dependency> 243 <groupId>org.codehaus.jackson</groupId> 244 <artifactId>jackson-mapper-asl</artifactId> 245 <version>${dep.ver.jackson}</version> 246 </dependency> 247 <!-- jackson --> 248 <!-- aspectj --> 249 <dependency> 250 <groupId>aspectj</groupId> 251 <artifactId>aspectjrt</artifactId> 252 <version>${dep.ver.aspectjrt}</version> 253 </dependency> 254 <dependency> 255 <groupId>org.aspectj</groupId> 256 <artifactId>aspectjweaver</artifactId> 257 <version>${dep.ver.aspectjweaver}</version> 258 </dependency> 259 <!-- aspectj --> 260 <!-- servlet --> 261 <dependency> 262 <groupId>javax.servlet</groupId> 263 <artifactId>javax.servlet-api</artifactId> 264 <version>${dep.ver.servlet}</version> 265 <scope>provided</scope> 266 </dependency> 267 <!-- servlet --> 268 <!-- javassist --> 269 <dependency> 270 <groupId>org.javassist</groupId> 271 <artifactId>javassist</artifactId> 272 <version>${dep.ver.javassist}</version> 273 </dependency> 274 <!-- javassist --> 275 <!-- test start --> 276 <dependency> 277 <groupId>junit</groupId> 278 <artifactId>junit</artifactId> 279 <version>${dep.ver.junit}</version> 280 <scope>test</scope> 281 </dependency> 282 <dependency> 283 <groupId>org.springframework</groupId> 284 <artifactId>spring-test</artifactId> 285 <version>${dep.ver.springframework}</version> 286 <scope>test</scope> 287 </dependency> 288 <dependency> 289 <groupId>org.mockito</groupId> 290 <artifactId>mockito-core</artifactId> 291 <version>${dep.ver.mockito}</version> 292 <scope>test</scope> 293 </dependency> 294 <!-- test end --> 295 <!-- google --> 296 <dependency> 297 <groupId>com.google.code.gson</groupId> 298 <artifactId>gson</artifactId> 299 <version>${dep.ver.gson}</version> 300 </dependency> 301 <dependency> 302 <groupId>com.google.guava</groupId> 303 <artifactId>guava</artifactId> 304 <version>${dep.ver.guava}</version> 305 </dependency> 306 <!-- google --> 307 <!-- lombok --> 308 <dependency> 309 <groupId>org.projectlombok</groupId> 310 <artifactId>lombok</artifactId> 311 <version>${dep.ver.lombok}</version> 312 </dependency> 313 <!-- lombok --> 314 <dependency> 315 <groupId>org.apache.commons</groupId> 316 <artifactId>commons-collections4</artifactId> 317 <version>${dep.ver.commons-collections4}</version> 318 </dependency> 319 <dependency> 320 <groupId>org.apache.httpcomponents</groupId> 321 <artifactId>httpclient</artifactId> 322 <version>${dep.ver.httpclient}</version> 323 <exclusions> 324 <exclusion> 325 <groupId>commons-logging</groupId> 326 <artifactId>commons-logging</artifactId> 327 </exclusion> 328 </exclusions> 329 </dependency> 330 </dependencies> 331 </dependencyManagement> 332 333 <profiles> 334 <profile> 335 <id>local</id> 336 <build> 337 <resources> 338 <resource> 339 <directory>${profiles.dir}/local</directory> 340 </resource> 341 </resources> 342 </build> 343 </profile> 344 345 <profile> 346 <id>dev</id> 347 <build> 348 <resources> 349 <resource> 350 <directory>${profiles.dir}/dev</directory> 351 </resource> 352 </resources> 353 </build> 354 </profile> 355 </profiles> 356 357 <build> 358 <finalName>${center.project.name}</finalName> 359 360 <plugins> 361 <plugin> 362 <groupId>org.apache.maven.plugins</groupId> 363 <artifactId>maven-resources-plugin</artifactId> 364 <version>${plg.ver.maven-resources-plugin}</version> 365 <configuration> 366 <encoding>${encoding}</encoding> 367 </configuration> 368 </plugin> 369 <plugin> 370 <groupId>org.apache.maven.plugins</groupId> 371 <artifactId>maven-compiler-plugin</artifactId> 372 <version>${plg.ver.maven-compiler-plugin}</version> 373 <configuration> 374 <source>${jdk.ver}</source> 375 <target>${jdk.ver}</target> 376 <encoding>${encoding}</encoding> 377 </configuration> 378 </plugin> 379 <plugin> 380 <artifactId>maven-source-plugin</artifactId> 381 <version>${plg.ver.maven-source-plugin}</version> 382 <configuration> 383 <attach>true</attach> 384 </configuration> 385 <executions> 386 <execution> 387 <phase>compile</phase> 388 <goals> 389 <goal>jar</goal> 390 </goals> 391 </execution> 392 </executions> 393 </plugin> 394 </plugins> 395 <resources> 396 <resource> 397 <directory>src/main/resources</directory> 398 <filtering>true</filtering> 399 </resource> 400 </resources> 401 </build> 402 </project>
View Code
在student-api中继承父pom的依赖,并且直接引入。
1 <?xml version="1.0"?> 2 <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" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>com.student.demo</groupId> 7 <artifactId>student-demo</artifactId> 8 <version>1.0.0-SNAPSHOT</version> 9 </parent> 10 <artifactId>student-api</artifactId> 11 12 <dependencies> 13 <dependency> 14 <groupId>com.alibaba</groupId> 15 <artifactId>fastjson</artifactId> 16 <version>${dep.ver.fastjson}</version> 17 </dependency> 18 19 <dependency> 20 <groupId>org.springframework</groupId> 21 <artifactId>spring-context</artifactId> 22 </dependency> 23 <dependency> 24 <groupId>org.springframework</groupId> 25 <artifactId>spring-web</artifactId> 26 </dependency> 27 <dependency> 28 <groupId>org.apache.httpcomponents</groupId> 29 <artifactId>httpclient</artifactId> 30 </dependency> 31 <!-- google --> 32 <dependency> 33 <groupId>com.google.code.gson</groupId> 34 <artifactId>gson</artifactId> 35 </dependency> 36 <dependency> 37 <groupId>com.google.guava</groupId> 38 <artifactId>guava</artifactId> 39 </dependency> 40 <!-- google --> 41 42 </dependencies> 43 </project>
View Code
在student-service中添加继承依赖,添加对student-api的依赖。
1 <?xml version="1.0"?> 2 <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" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>com.student.demo</groupId> 7 <artifactId>student-demo</artifactId> 8 <version>1.0.0-SNAPSHOT</version> 9 </parent> 10 <artifactId>student-service</artifactId> 11 12 <dependencies> 13 <dependency> 14 <groupId>com.student.demo</groupId> 15 <artifactId>student-api</artifactId> 16 <version>1.0.0-SNAPSHOT</version> 17 </dependency> 18 19 <dependency> 20 <groupId>com.alibaba</groupId> 21 <artifactId>fastjson</artifactId> 22 <version>${dep.ver.fastjson}</version> 23 </dependency> 24 25 <!-- oss相关依赖 --> 26 <dependency> 27 <groupId>com.aliyun.oss</groupId> 28 <artifactId>aliyun-sdk-oss</artifactId> 29 <version>2.0.7</version> 30 <exclusions> 31 <exclusion> 32 <groupId>commons-logging</groupId> 33 <artifactId>commons-logging</artifactId> 34 </exclusion> 35 </exclusions> 36 </dependency> 37 <!-- oss相关依赖 结束 --> 38 39 <!-- db --> 40 <dependency> 41 <groupId>com.alibaba</groupId> 42 <artifactId>druid</artifactId> 43 </dependency> 44 <dependency> 45 <groupId>mysql</groupId> 46 <artifactId>mysql-connector-java</artifactId> 47 </dependency> 48 <!-- db --> 49 50 <!-- mybatis --> 51 <dependency> 52 <groupId>org.mybatis</groupId> 53 <artifactId>mybatis</artifactId> 54 </dependency> 55 <dependency> 56 <groupId>org.mybatis</groupId> 57 <artifactId>mybatis-spring</artifactId> 58 </dependency> 59 <dependency> 60 <groupId>com.github.pagehelper</groupId> 61 <artifactId>pagehelper</artifactId> 62 </dependency> 63 <!-- mybatis --> 64 65 <!-- spring配置 --> 66 <dependency> 67 <groupId>org.springframework</groupId> 68 <artifactId>spring-core</artifactId> 69 </dependency> 70 <dependency> 71 <groupId>org.springframework</groupId> 72 <artifactId>spring-context</artifactId> 73 </dependency> 74 <dependency> 75 <groupId>org.springframework</groupId> 76 <artifactId>spring-webmvc</artifactId> 77 </dependency> 78 <dependency> 79 <groupId>org.springframework</groupId> 80 <artifactId>spring-jdbc</artifactId> 81 </dependency> 82 <dependency> 83 <groupId>org.springframework</groupId> 84 <artifactId>spring-context-support</artifactId> 85 </dependency> 86 <dependency> 87 <groupId>org.springframework</groupId> 88 <artifactId>spring-tx</artifactId> 89 </dependency> 90 <dependency> 91 <groupId>org.springframework</groupId> 92 <artifactId>spring-aspects</artifactId> 93 </dependency> 94 <!-- spring配置 --> 95 96 <!-- jackson --> 97 <!-- <dependency> --> 98 <!-- <groupId>org.codehaus.jackson</groupId> --> 99 <!-- <artifactId>jackson-core-asl</artifactId> --> 100 <!-- </dependency> --> 101 <!-- <dependency> --> 102 <!-- <groupId>org.codehaus.jackson</groupId> --> 103 <!-- <artifactId>jackson-mapper-asl</artifactId> --> 104 <!-- </dependency> --> 105 <dependency> 106 <groupId>com.fasterxml.jackson.core</groupId> 107 <artifactId>jackson-core</artifactId> 108 <version>${jackson.version}</version> 109 </dependency> 110 <dependency> 111 <groupId>com.fasterxml.jackson.core</groupId> 112 <artifactId>jackson-databind</artifactId> 113 <version>${jackson.version}</version> 114 </dependency> 115 <dependency> 116 <groupId>com.fasterxml.jackson.core</groupId> 117 <artifactId>jackson-annotations</artifactId> 118 <version>${jackson.version}</version> 119 </dependency> 120 <!-- jackson --> 121 122 <!-- log --> 123 <dependency> 124 <groupId>org.slf4j</groupId> 125 <artifactId>slf4j-api</artifactId> 126 </dependency> 127 <dependency> 128 <groupId>ch.qos.logback</groupId> 129 <artifactId>logback-classic</artifactId> 130 </dependency> 131 <dependency> 132 <groupId>org.slf4j</groupId> 133 <artifactId>log4j-over-slf4j</artifactId> 134 </dependency> 135 <dependency> 136 <groupId>org.slf4j</groupId> 137 <artifactId>jcl-over-slf4j</artifactId> 138 </dependency> 139 <!-- log --> 140 141 <!-- google --> 142 <dependency> 143 <groupId>com.google.guava</groupId> 144 <artifactId>guava</artifactId> 145 </dependency> 146 <!-- <dependency> --> 147 <!-- <groupId>com.google.code.gson</groupId> --> 148 <!-- <artifactId>gson</artifactId> --> 149 <!-- </dependency> --> 150 <!-- google --> 151 152 <dependency> 153 <groupId>org.apache.commons</groupId> 154 <artifactId>commons-lang3</artifactId> 155 </dependency> 156 157 <dependency> 158 <groupId>commons-beanutils</groupId> 159 <artifactId>commons-beanutils</artifactId> 160 </dependency> 161 162 <dependency> 163 <groupId>javax.servlet</groupId> 164 <artifactId>javax.servlet-api</artifactId> 165 </dependency> 166 167 <dependency> 168 <groupId>org.javassist</groupId> 169 <artifactId>javassist</artifactId> 170 </dependency> 171 172 <!-- aspectj --> 173 <dependency> 174 <groupId>aspectj</groupId> 175 <artifactId>aspectjrt</artifactId> 176 </dependency> 177 <dependency> 178 <groupId>org.aspectj</groupId> 179 <artifactId>aspectjweaver</artifactId> 180 </dependency> 181 <!-- aspectj --> 182 183 <!-- dubbo --> 184 <dependency> 185 <groupId>com.alibaba</groupId> 186 <artifactId>dubbo</artifactId> 187 <exclusions> 188 <exclusion> 189 <artifactId>spring</artifactId> 190 <groupId>org.springframework</groupId> 191 </exclusion> 192 <exclusion> 193 <artifactId>netty</artifactId> 194 <groupId>org.jboss.netty</groupId> 195 </exclusion> 196 </exclusions> 197 </dependency> 198 <dependency> 199 <groupId>org.apache.zookeeper</groupId> 200 <artifactId>zookeeper</artifactId> 201 <exclusions> 202 <exclusion> 203 <groupId>org.slf4j</groupId> 204 <artifactId>slf4j-log4j12</artifactId> 205 </exclusion> 206 </exclusions> 207 </dependency> 208 <dependency> 209 <groupId>com.101tec</groupId> 210 <artifactId>zkclient</artifactId> 211 <exclusions> 212 <exclusion> 213 <groupId>org.slf4j</groupId> 214 <artifactId>slf4j-log4j12</artifactId> 215 </exclusion> 216 </exclusions> 217 </dependency> 218 <!-- dubbo --> 219 220 <dependency> 221 <groupId>org.apache.httpcomponents</groupId> 222 <artifactId>httpclient</artifactId> 223 </dependency> 224 225 <dependency> 226 <groupId>cglib</groupId> 227 <artifactId>cglib</artifactId> 228 <version>3.1</version> 229 </dependency> 230 </dependencies> 231 </project>
View Code
在student-web中继承依赖,添加对student-api,student-service的依赖。注意子项目依赖版本都为<version>1.0.0-SNAPSHOT</version>
1 <?xml version="1.0"?> 2 <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" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>com.student.demo</groupId> 7 <artifactId>student-demo</artifactId> 8 <version>1.0.0-SNAPSHOT</version> 9 </parent> 10 <artifactId>student-web</artifactId> 11 <packaging>war</packaging> 12 <dependencies> 13 <dependency> 14 <groupId>junit</groupId> 15 <artifactId>junit</artifactId> 16 </dependency> 17 18 <dependency> 19 <groupId>com.student.demo</groupId> 20 <artifactId>student-api</artifactId> 21 <version>1.0.0-SNAPSHOT</version> 22 </dependency> 23 <dependency> 24 <groupId>com.student.demo</groupId> 25 <artifactId>student-service</artifactId> 26 <version>1.0.0-SNAPSHOT</version> 27 </dependency> 28 </dependencies> 29 <build> 30 <finalName>student-web</finalName> 31 </build> 32 </project>
View Code
二、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>
View Code
同样DispatcherServlet会从classpath:spring/spring-dispatcher.xml加载它的bean。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-3.0.xsd 9 http://www.springframework.org/schema/mvc 10 http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 11 12 <mvc:annotation-driven> 13 <mvc:message-converters> 14 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter " /> 15 </mvc:message-converters> 16 </mvc:annotation-driven> 17 18 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 19 <!-- 相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个bean,配置一些messageconverter。即解决了@Controller注解的使用前提配置 --> 20 </beans>
View Code
4.在Web.xml中声明DispatcherServlet
SpringMVC所有请求都会通过一个前端控制器DispatcherServlet,通过这个控制器将请求委托给应用程序的其它执行单元来处理,所以需要通过web.xml来注册。打开student-web项目目录下src/main/webapp/WEB-INF/web.xml,修改web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 5 id="schedule-console" version="3.0"> 6 <display-name>student-web</display-name> 7 8 <!-- web.xml中加载顺序是 context-param -> listener -> filter -> servlet --> 9 <!-- spring基础配置文件位置 --> 10 <context-param> 11 <param-name>contextConfigLocation</param-name> 12 <param-value>classpath:spring/spring-base.xml</param-value> 13 </context-param> 14 15 <!-- Spring监听 --> 16 <listener> 17 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 18 </listener> 19 <!-- 设置servlet编码开始 --> 20 <filter> 21 <filter-name>characterEncodingFilter</filter-name> 22 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 23 <init-param> 24 <param-name>encoding</param-name> 25 <param-value>UTF-8</param-value> 26 </init-param> 27 <init-param> 28 <param-name>forceEncoding</param-name> 29 <param-value>true</param-value> 30 </init-param> 31 </filter> 32 <filter-mapping> 33 <filter-name>characterEncodingFilter</filter-name> 34 <url-pattern>/*</url-pattern> 35 </filter-mapping> 36 <!-- 设置servlet编码结束 --> 37 <servlet> 38 <servlet-name>dispatcher</servlet-name> 39 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 40 <init-param> 41 <param-name>contextConfigLocation</param-name> 42 <param-value>classpath:spring/spring-dispatcher.xml</param-value> 43 </init-param> 44 </servlet> 45 <servlet-mapping> 46 <servlet-name>dispatcher</servlet-name> 47 <url-pattern>/</url-pattern> 48 </servlet-mapping> 49 </web-app>
View Code
5.spring与Mybatis的整合
在student-web的src/main/resources目录中新建mybatis文件夹,再在此目录新建mybatis.xml和mapper文件夹。在spring文件夹下新建spring-db.xml用于spring加载mybatis配置。spring-db.xml内容如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.0.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 11 12 <!-- 采用druid作为连接池 --> 13 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 14 init-method="init" destroy-method="close"> 15 <!-- 基本属性 url、user、password --> 16 <property name="driverClassName" value="${database.driverClassName}" /> 17 <property name="url" value="${database.url}" /> 18 <property name="username" value="${database.user}" /> 19 <property name="password" value="${database.password}" /> 20 21 <!-- 配置初始化大小、最小、最大 --> 22 <property name="initialSize" value="1" /> 23 <property name="minIdle" value="1" /> 24 <property name="maxActive" value="20" /> 25 26 <!-- 配置获取连接等待超时的时间 --> 27 <property name="maxWait" value="60000" /> 28 29 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> 30 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 31 32 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> 33 <property name="minEvictableIdleTimeMillis" value="300000" /> 34 <property name="validationQuery" value="SELECT 'x'" /> 35 <property name="testWhileIdle" value="true" /> 36 <property name="testOnBorrow" value="false" /> 37 <property name="testOnReturn" value="false" /> 38 39 <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --> 40 <property name="poolPreparedStatements" value="true" /> 41 <property name="maxPoolPreparedStatementPerConnectionSize" 42 value="20" /> 43 44 <!-- 配置监控统计拦截的filters --> 45 <property name="filters" value="stat" /> 46 </bean> 47 48 <!-- 配置mybatis的sqlSessionFactory --> 49 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 50 <property name="dataSource" ref="dataSource" /> 51 <property name="configLocation" value="classpath:mybatis/mybatis.xml" /> 52 <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" /> 53 </bean> 54 55 <!-- mybatis mapper接口扫描 --> 56 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 57 <property name="basePackage" value="org.student.service.mapper" /> 58 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> 59 </bean> 60 61 <bean id="transactionManager" 62 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 63 <property name="dataSource" ref="dataSource" /> 64 </bean> 65 66 <!-- 开启@Transactional事务注解 --> 67 <tx:annotation-driven transaction-manager="transactionManager" /> 68 </beans>
View Code
三、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>
View Code
2.写一个简单的服务接口
1)首先在student-service中建立Student实体类
1 package org.student.bean; 2 3 public class Student { 4 private Long id; 5 private String name; 6 private Integer age; 7 public Long getId() { 8 return id; 9 } 10 public void setId(Long id) { 11 this.id = id; 12 } 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 this.name = name; 18 } 19 public Integer getAge() { 20 return age; 21 } 22 public void setAge(Integer age) { 23 this.age = age; 24 } 25 26 27 }
View Code
2)同时在student-api中建立与实体bean对应的DTO类实现Serializable接口,并重写toString方法。一般为了不破坏实体类和数据库表一一对应的接口,我们会新建一个DTO实体类,并且加入一些冗余的字段,作为前后端的传输对象。
1 package org.student.api.dto; 2 3 import java.io.Serializable; 4 5 public class StudentDTO implements Serializable{ 6 7 private static final long serialVersionUID = 1L; 8 private Long id; 9 private String name; 10 private Integer age; 11 public Long getId() { 12 return id; 13 } 14 public void setId(Long id) { 15 this.id = id; 16 } 17 public String getName() { 18 return name; 19 } 20 public void setName(String name) { 21 this.name = name; 22 } 23 public Integer getAge() { 24 return age; 25 } 26 public void setAge(Integer age) { 27 this.age = age; 28 } 29 30 @Override 31 public String toString() { 32 return "id = " + id + ", name = " + name + ",age = " + age; 33 } 34 35 36 }
View Code
3)在student-api中建立StudentApi接口,值得注意的是@service注解中的对象
1 package org.student.api; 2 3 import java.util.List; 4 5 import org.student.api.dto.StudentDTO; 6 7 public interface StudentApi { 8 List<StudentDTO> listStudents(); 9 }
View Code
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接口
1 package org.student.service.biz; 2 3 import java.util.List; 4 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.stereotype.Service; 9 import org.student.api.StudentApi; 10 import org.student.api.dto.StudentDTO; 11 import org.student.bean.Student; 12 import org.student.service.StudentService; 13 14 import com.google.common.collect.Lists; 15 16 @Service("studentApi") 17 public class StudentBiz implements StudentApi{ 18 private Logger logger = LoggerFactory.getLogger(StudentBiz.class); 19 20 @Autowired 21 private StudentService studentService; 22 23 @Override 24 public List<StudentDTO> listStudents() { 25 List<Student> listStudent = studentService.listStudent(); 26 List<StudentDTO> listStudentDTO = Lists.newArrayList(); 27 for(Student student: listStudent){ 28 StudentDTO studentDTO = new StudentDTO(); 29 studentDTO.setId(student.getId()); 30 studentDTO.setAge(student.getAge()); 31 studentDTO.setName(student.getName()); 32 listStudentDTO.add(studentDTO); 33 } 34 return listStudentDTO; 35 } 36 }
View Code
6)在student-service中创建service层接口StudentService
1 package org.student.service; 2 3 import java.util.List; 4 5 import org.springframework.stereotype.Service; 6 import org.student.bean.Student; 7 8 @Service 9 public interface StudentService { 10 11 List<Student> listStudent(); 12 13 }
View Code
7)在student-service中实现StudentService接口
1 package org.student.service.impl; 2 3 import java.util.List; 4 5 import javax.annotation.Resource; 6 7 import org.springframework.stereotype.Service; 8 import org.student.bean.Student; 9 import org.student.service.StudentService; 10 import org.student.service.mapper.StudentMapper; 11 12 @Service("studentService") 13 public class StudentServiceImpl implements StudentService{ 14 15 @Resource 16 private StudentMapper studentMapper; 17 18 @Override 19 public List<Student> listStudent() { 20 List<Student> listStudent = studentMapper.listStudent(); 21 return listStudent; 22 } 23 24 }
View Code
8)在student-service中创建数据层StudentMapper接口
1 package org.student.service.mapper; 2 3 import java.util.List; 4 5 import org.student.bean.Student; 6 7 public interface StudentMapper { 8 List<Student> listStudent(); 9 }
View Code
9)在student-web中创建实体映射的XML文件,注意StudentMapper类与sql ID的对应关系
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 3 <mapper namespace="org.student.service.mapper.StudentMapper"> 4 <!--查询字段--> 5 <sql id="columns"> 6 a.id, 7 a.name, 8 a.age 9 </sql> 10 11 <!--查询结果集--> 12 <resultMap id="beanMap" type="org.student.bean.Student"> 13 <result property="id" column="id"/> 14 <result property="name" column="name"/> 15 <result property="age" column="age"/> 16 </resultMap> 17 18 19 <!--根据主键获取实体--> 20 <select id="listStudent" resultMap="beanMap"> 21 SELECT 22 <include refid="columns"/> 23 FROM 24 student a 25 </select> 26 27 </mapper>
View Code
dubbo提供者已创建完成,创建完成子应用结构为
3.为了更好的验证,需要创建一个消费者,跳用dubbo接口,其项目结构与子项目student-web类似,Maven项目类型为Webapp project。为了不冗余介绍,请参考Maven项目搭建方式。其将建完成的结构为: 作为消费者,student-test项目的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>
1 student-registry-address=172.0.0.1:2181 2 student-service-group=student-min 3 student-service-version=1.0.0 4 student-service-timeout=120000
2)spring-dubbo-consumer.xml的配置及接口调用方式
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 10 http://code.alibabatech.com/schema/dubbo 11 http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> 12 13 <dubbo:application name="consumer-student-test" /> 14 15 <dubbo:registry address="${student-registry-address}" protocol="zookeeper" /> 16 17 18 <dubbo:reference id="studentApi" interface="org.student.api.StudentApi" 19 group="${student-service-group}" version="${student-service-version}" 20 check="false" /> 21 22 </beans>
View Code
3)调用者的controller层
1 package org.student.controller; 2 3 import javax.annotation.Resource; 4 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RestController; 10 import org.student.api.StudentApi; 11 12 @RestController 13 @RequestMapping("/student") 14 public class StudentController { 15 private static Logger logger = LoggerFactory.getLogger(StudentController.class); 16 17 @Resource 18 private StudentApi studentApi; 19 20 @RequestMapping(path = "/listStudent", method = RequestMethod.POST) 21 public void listStudent(){ 22 logger.info("get students..."); 23 logger.info("the data are " + studentApi.listStudents()); 24 } 25 }
4)服务器同时启动provider和consumer,会看到启动信息
查看zookeeper注册中心发现提供者消费者都已成功注册
5)测试接口 由于我并没有写view层来展示数据,现在只能通过控制台的日志信息来简单测试接口。(logback的用法不做解释)利用浏览器post请求访问http://172.0.0.1:8080/student-test/student/listStudent,控制台输出为
[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 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListenerat org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166)at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:518)at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:499)at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4764)at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)
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中添加
<context:component-scan base-package="org.student" />
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 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)....
如果消费者访问的接口路径不正确,则无法调用接口。出现这种错误是我没有把消费者的组设置成提供者的组,解决方法是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中加上扫描。
博客推荐:
http://blessht.iteye.com/blog/2121845
http://www.cnblogs.com/szlbm/p/5512931.html
http://blog.csdn.net/congcong68/article/details/41113239
PS:太多朋友需要源码,可能没有及时回复邮件。现我已上传至Github,请自行下载,欢迎大家多做交流。 student-demo student-test
转载于:https://www.cnblogs.com/blueness-sunshine/p/6015965.html
Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题...相关推荐
- 前后端分离项目全环境搭建(Ruoyi框架)
记录一下在全新的电脑上搭建前后端分离项目的全过程,方便下次继续Copy.(以Ruoyi框架为例子进行操作) 目录 前端 1.VsCode 2.NodeJs 后端 JDK idea Tomcat Mav ...
- myBatis-plus实现先按条件查询,再把查询结果分页(基于xboot框架的前后端分离项目的一部分)
一.数据库 业务需求:查询数据库表test_point(里面有十个温度测试点,不同测试点有不同时间的测试温度),要把十个点的各自最新时间的数据拿到,再分页展示到页面上. sql文件: /* SQLyo ...
- dubbo分布式服务框架(高级特性篇)
目录 1.序列化 2.地址缓存 3.超时 4.重试 5.多版本 6.负载均衡 7.集群容错 8.服务降级 本文参考b站黑马程序员dubbo入门课程 视频连接:黑马程序员Dubbo快速入门,Java分布 ...
- 首个直播商城,拼团商城,小程序商城的微服务分布式框架,前后端分离
简介: sdb mall 项目说明 sdb是一个轻量级的在renren-fast基础上利用jfinal架构二次开发的一个极速二次开发直播,拼团商城框架,前后端分离的Java快速开发平台,C端采用微信小 ...
- 【两万字图文详解】 运动会管理系统-前后端分离-项目开发:【后端】SpringBoot, SpringMVC, MyBatis【前端】Vue.js,ElementUI
项目名称:运动会管理系统 技术栈: 后端:SpringBoot,SpringMVC,MyBatis,tkmapper,Maven聚合工程等 前端:Vue.js,Element-u ...
- vue和Java做数据交互_基于vue和springmvc前后端分离,json类接口调用介绍
基于vue和springmvc前后端分离,json类接口调用介绍 版本要求:spring-3.2.9.RELEASE.vue-2.9.2.axios-0.17.1,其中axios作为http clie ...
- SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【后端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】
前后端分离项目快速搭建[后端篇] 数据库准备 后端搭建 1.快速创建个SpringBoot项目 2.引入依赖 3.编写代码快速生成代码 4.运行代码生成器生成代码 5.编写application.pr ...
- crm开源系统 tp框架_八个开源的 Spring Boot 前后端分离项目,一定要收藏!
点击蓝色字关注我们 前后端分离已经在慢慢走进各公司的技术栈,不少公司都已经切换到这个技术栈上面了.即使贵司目前没有切换到这个技术栈上面,也非常建议大家学习一下前后端分离开发,以免在公司干了两三年,SS ...
- 基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台、多租户
基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台.多租户.支持MySQL/SQLServer/ ...
- SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【前端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】
前后端分离项目快速搭建[前端篇] 后端篇 前端篇 创建vue项目 安装所需工具 开始编码 1.在根目录下添加vue.config.js文件 2.编写main.js 3.编写App.vue 4.编写ax ...
最新文章
- Glide二次封装库的使用
- java平台类成员访问修饰符_JAVA类的修饰符及访问权限
- 为什么在C#中捕获并抛出异常?
- Java基础 之软引用、弱引用、虚引用
- 推荐:两款实用的Jupyter插件~
- 现在开始(译) 明确的知道你想要什麽是关键 每次 只做一件事的习惯 成功的人是因为屡次尝试经历失败保持激情 动手一试...
- 开源 java CMS - FreeCMS2.2 系统配置
- Java 中的并发工具类
- 武汉大学计算机系学哪些专业,武汉大学最好的专业是什么(10大热门专业排名)...
- (一)在GKE上创建MLOps Kubernetes集群
- 为什么程序必须得会C语言?
- 数码相机专业术语解答
- Python接口自动化实战(第二阶段)- unittest框架
- IIS7的应用程序池详细解析
- 车载蓝牙音频系统测试
- windows如何卸载服务
- 迅捷CAD编辑器剪切框架工具具体使用方法
- Python 基础知识 Day2
- 修改postgresql库表的owner
- 《动态壁纸 : 手机壁纸大全》EULA条款协议
热门文章
- 一起Polyfill系列:Function.prototype.bind的四个阶段
- happens-before规则和as-if-serial语义
- Mac安装nginx配置过程
- CountDownLatch,CyclicBarrier和Semaphore
- windows下python安装Numpy、Scipy、matplotlib模块
- Java学习进阶—高级编程
- 《中国人工智能学会通讯》——11.21 结束语
- 笨办法学C 练习45:一个简单的TCP/IP客户端
- Python数值计算:一 使用Pylab绘图(1)
- 关于工作的选择之软件开发还是软件维护的建议