現互聯網公司後端架構經常使用到Spring+SpringMVC+MyBatis,經過Maven來構建。經過學習,我已經掌握了基本的搭建過程,寫下基礎文章爲然後的深刻學習奠基基礎。html
首先說一下這篇文章的主要內容分爲:前端
一、Maven多模塊項目的建立;java
二、Maven與SpringMVC的整合;mysql
三、Dubbo的環境配置及與整合;git
四、新手在整合過程易犯的錯誤。github
經過一個簡單的demo來講明,你們多多指教,分享經驗!web
1、Maven多模塊項目的建立spring
咱們須要創建一個多模塊的maven項目,其目錄結構爲sql
其中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>
在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>
在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>
在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>
2、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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://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。
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>
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>
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>
3、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/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">
<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實體類
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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>
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>
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]
4、新手在整合過程易犯的錯誤。
1.ClassNotFound異常
嚴重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener at 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