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將jar修改為pom,pom表示它是一個被繼承的模塊。修改后的pom.xml如下

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT

pom

student-demo

http://maven.apache.org

UTF-8


student-service

student-api

student-web

junit

junit

3.8.1

test

在建成的項目student-demo上右鍵選擇Maven Module后創建子項目student-api。

    填寫子模塊名字:

    項目類型選擇:

    點擊完成,建立好第一個模塊后,同樣的過程建立好student-service模塊和student-web模塊,需要注意的是student-web選擇的maven類型是:

修改子模塊項目目錄中的pom.xml文件,把XXX和1.0.0-SNAPSHOT去掉,加上jar,因為groupId和version會繼承student-demo中的groupId和version,packaging設置打包方式為jar。例如修改后的student-service模塊的pom.xml如下:


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT


student-service

jar

至此,maven多模塊項目已經創建完成,現在我們需要在student-demo項目的pom中增加標簽定義可被子項目繼承的第三方依賴包,打包配置,資源插件等,同時注意統一定義依賴的版本,避免沖突。這里還利用Maven配置了profiles,可根據情況增加不同的運行環境,并方便快捷地切換項目運行環境,目前我們只設置了dev開發環境。

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT

pom

UTF-8

1.16.10

1.0.1

5.1.21

4.2.5.RELEASE

3.3.0

1.3.0

4.1.6

1.5.4

1.8.0

3.1.0

1.4.6

3.20.0-GA

2.7

1.4.2

2.2.4

15.0

1.7.21

1.1.7

1.2.12

1.7.5

0.1.2

2.5.3

3.4.8

0.8

3.1

1.9.12

1.2.3

2.3.22

1.9.2

4.11

1.10.19

2.9.3

4.1

4.5.2

1.2.11

2.7

2.5.1

3.0.0

1.14.8.0

1.8

UTF-8

${project.artifactId}

src/profiles

2.6.0

student-service

student-api

student-web


org.hibernate

hibernate-validator

5.2.4.Final



org.springframework

spring-core

${dep.ver.springframework}

commons-logging

commons-logging

org.springframework

spring-context

${dep.ver.springframework}

org.springframework

spring-context-support

${dep.ver.springframework}

org.springframework

spring-web

${dep.ver.springframework}

org.springframework

spring-webmvc

${dep.ver.springframework}

org.springframework

spring-jdbc

${dep.ver.springframework}

org.springframework

spring-tx

${dep.ver.springframework}

org.springframework

spring-aspects

${dep.ver.springframework}



com.alibaba

druid

${dep.ver.druid}

mysql

mysql-connector-java

${dep.ver.mysql}



org.mybatis

mybatis

${dep.ver.mybatis}

org.mybatis

mybatis-spring

${dep.ver.mybatis-spring}

com.github.pagehelper

pagehelper

${dep.ver.pagehelper}



org.apache.commons

commons-lang3

${dep.ver.commons-lang3}



commons-beanutils

commons-beanutils

${dep.ver.commons-beanutils}

commons-logging

commons-logging



org.slf4j

slf4j-api

${dep.ver.slf4j}

org.slf4j

log4j-over-slf4j

${dep.ver.slf4j}

org.slf4j

jcl-over-slf4j

${dep.ver.slf4j}

ch.qos.logback

logback-classic

${dep.ver.logback}



com.alibaba

dubbo

${dep.ver.dubbo}

spring

org.springframework

netty

org.jboss.netty



org.apache.zookeeper

zookeeper

${dep.ver.zookeeper}

log4j

log4j

com.101tec

zkclient

${dep.ver.zkclient}

log4j

log4j



org.codehaus.jackson

jackson-core-asl

${dep.ver.jackson}

org.codehaus.jackson

jackson-mapper-asl

${dep.ver.jackson}



aspectj

aspectjrt

${dep.ver.aspectjrt}

org.aspectj

aspectjweaver

${dep.ver.aspectjweaver}



javax.servlet

javax.servlet-api

${dep.ver.servlet}

provided



org.javassist

javassist

${dep.ver.javassist}



junit

junit

${dep.ver.junit}

test

org.springframework

spring-test

${dep.ver.springframework}

test

org.mockito

mockito-core

${dep.ver.mockito}

test



com.google.code.gson

gson

${dep.ver.gson}

com.google.guava

guava

${dep.ver.guava}



org.projectlombok

lombok

${dep.ver.lombok}


org.apache.commons

commons-collections4

${dep.ver.commons-collections4}

org.apache.httpcomponents

httpclient

${dep.ver.httpclient}

commons-logging

commons-logging


local

${profiles.dir}/local

dev

${profiles.dir}/dev

${center.project.name}

org.apache.maven.plugins

maven-resources-plugin

${plg.ver.maven-resources-plugin}

${encoding}

org.apache.maven.plugins

maven-compiler-plugin

${plg.ver.maven-compiler-plugin}

${jdk.ver}

${jdk.ver}

${encoding}

maven-source-plugin

${plg.ver.maven-source-plugin}

true

compile

jar

src/main/resources

true

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


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT

student-api

com.alibaba

fastjson

${dep.ver.fastjson}

org.springframework

spring-context

org.springframework

spring-web

org.apache.httpcomponents

httpclient


com.google.code.gson

gson

com.google.guava

guava


在student-service中添加繼承依賴,添加對student-api的依賴。


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT

student-service

com.student.demo

student-api

1.0.0-SNAPSHOT

com.alibaba

fastjson

${dep.ver.fastjson}


com.aliyun.oss

aliyun-sdk-oss

2.0.7

commons-logging

commons-logging



com.alibaba

druid

mysql

mysql-connector-java



org.mybatis

mybatis

org.mybatis

mybatis-spring

com.github.pagehelper

pagehelper



org.springframework

spring-core

org.springframework

spring-context

org.springframework

spring-webmvc

org.springframework

spring-jdbc

org.springframework

spring-context-support

org.springframework

spring-tx

org.springframework

spring-aspects











com.fasterxml.jackson.core

jackson-core

${jackson.version}

com.fasterxml.jackson.core

jackson-databind

${jackson.version}

com.fasterxml.jackson.core

jackson-annotations

${jackson.version}



org.slf4j

slf4j-api

ch.qos.logback

logback-classic

org.slf4j

log4j-over-slf4j

org.slf4j

jcl-over-slf4j



com.google.guava

guava






org.apache.commons

commons-lang3

commons-beanutils

commons-beanutils

javax.servlet

javax.servlet-api

org.javassist

javassist


aspectj

aspectjrt

org.aspectj

aspectjweaver



com.alibaba

dubbo

spring

org.springframework

netty

org.jboss.netty

org.apache.zookeeper

zookeeper

org.slf4j

slf4j-log4j12

com.101tec

zkclient

org.slf4j

slf4j-log4j12


org.apache.httpcomponents

httpclient

cglib

cglib

3.1

在student-web中繼承依賴,添加對student-api,student-service的依賴。注意子項目依賴版本都為1.0.0-SNAPSHOT


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

com.student.demo

student-demo

1.0.0-SNAPSHOT

student-web

war

junit

junit


com.student.demo

student-api

1.0.0-SNAPSHOT

com.student.demo

student-service

1.0.0-SNAPSHOT

student-web

  二、Maven與SpringMVC的整合

    1.第一部分已經在項目pom文件中配置了spring的相關依賴

    2.在student-web項目根路徑上添加profiles源目錄及配置文件

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

     然后在此源文件夾下建立普通文件夾props,用于存放配置文件。在props下新建db-config.properties資源文件,用于配置mysql,其配置內容為:

1database.database=mysql2database.driverClassName=com.mysql.jdbc.Driver3database.url=jdbc:mysql://172.0.0.1:3306/student_data?characterEncoding=utf84database.user=root5database.password=root6database.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中的內容為:


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">



class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

classpath:props/db-config.properties

   ? 同樣DispatcherServlet會從classpath:spring/spring-dispatcher.xml加載它的bean。


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/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://www.springframework.org/schema/mvc

? ? ? ? ? ? ? ? ? ? ? ? http://www.springframework.org/schema/mvc/spring-mvc.xsd">


   4.在Web.xml中聲明DispatcherServlet

     SpringMVC所有請求都會通過一個前端控制器DispatcherServlet,通過這個控制器將請求委托給應用程序的其它執行單元來處理,所以需要通過web.xml來注冊。打開student-web項目目錄下src/main/webapp/WEB-INF/web.xml,修改web.xml


xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

id="schedule-console"version="3.0">

student-web



contextConfigLocation

classpath:spring/spring-base.xml


org.springframework.web.context.ContextLoaderListener


characterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

characterEncodingFilter

/*


dispatcher

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:spring/spring-dispatcher.xml

dispatcher

/

     5.spring與Mybatis的整合

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


xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

? ? ? ? http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

? ? ? ? http://www.springframework.org/schema/context?

? ? ? ? http://www.springframework.org/schema/context/spring-context-4.0.xsd

? ? ? ? http://www.springframework.org/schema/tx

? ? ? ? http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">


init-method="init"destroy-method="close">







value="20"/>




class="org.springframework.jdbc.datasource.DataSourceTransactionManager">


?   三、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分組,服務端口,注冊中心請求超時時間(毫秒)和版本。其中組別+接口地址+版本號唯一的標識了一個接口。文件內容為:

1student-registry-address=172.0.0.1:21812student-group=student-min3student-service-port=220264student-timeout=1200005student-version=1.0.0

這樣我們就可以來配置dubbo-producer.xml


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">



     2.寫一個簡單的服務接口

     1)首先在student-service中建立Student實體類

packageorg.student.bean;

publicclassStudent{

privateLong id;

privateString name;

privateInteger age;

publicLonggetId(){

returnid;

? ? }

publicvoidsetId(Long id){

this.id = id;

? ? }

publicStringgetName(){

returnname;

? ? }

publicvoidsetName(String name){

this.name = name;

? ? }

publicIntegergetAge(){

returnage;

? ? }

publicvoidsetAge(Integer age){

this.age = age;

? ? }


}

     2)同時在student-api中建立與實體bean對應的DTO類實現Serializable接口,并重寫toString方法。一般為了不破壞實體類和數據庫表一一對應的接口,我們會新建一個DTO實體類,并且加入一些冗余的字段,作為前后端的傳輸對象。

packageorg.student.api.dto;

importjava.io.Serializable;

publicclassStudentDTOimplementsSerializable{


privatestaticfinallongserialVersionUID =1L;

privateLong id;

privateString name;

privateInteger age;

publicLonggetId(){

returnid;

? ? }

publicvoidsetId(Long id){

this.id = id;

? ? }

publicStringgetName(){

returnname;

? ? }

publicvoidsetName(String name){

this.name = name;

? ? }

publicIntegergetAge(){

returnage;

? ? }

publicvoidsetAge(Integer age){

this.age = age;

? ? }


@Override

publicStringtoString(){

return"id = "+ id +", name = "+ name +",age = "+ age;

? ? }

}

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

packageorg.student.api;

importjava.util.List;

importorg.student.api.dto.StudentDTO;

publicinterfaceStudentApi{

ListlistStudents();

}

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

     5)從service業務邏輯層子模塊開始編寫接口實現,新建在student-service中新建StudentBiz實現StudentApi接口

packageorg.student.service.biz;

importjava.util.List;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.stereotype.Service;

importorg.student.api.StudentApi;

importorg.student.api.dto.StudentDTO;

importorg.student.bean.Student;

importorg.student.service.StudentService;

importcom.google.common.collect.Lists;

@Service("studentApi")

publicclassStudentBizimplementsStudentApi{

privateLogger logger = LoggerFactory.getLogger(StudentBiz.class);


@Autowired

privateStudentService studentService;


@Override

publicListlistStudents(){

? ? ? ? List listStudent = studentService.listStudent();

? ? ? ? List listStudentDTO = Lists.newArrayList();

for(Student student: listStudent){

StudentDTO studentDTO =newStudentDTO();

? ? ? ? ? ? studentDTO.setId(student.getId());

? ? ? ? ? ? studentDTO.setAge(student.getAge());

? ? ? ? ? ? studentDTO.setName(student.getName());

? ? ? ? ? ? listStudentDTO.add(studentDTO);

? ? ? ? }

returnlistStudentDTO;

? ? }

}

     6)在student-service中創建service層接口StudentService

packageorg.student.service;

importjava.util.List;

importorg.springframework.stereotype.Service;

importorg.student.bean.Student;

@Service

publicinterfaceStudentService{

ListlistStudent();


}

7)在student-service中實現StudentService接口

packageorg.student.service.impl;

importjava.util.List;

importjavax.annotation.Resource;

importorg.springframework.stereotype.Service;

importorg.student.bean.Student;

importorg.student.service.StudentService;

importorg.student.service.mapper.StudentMapper;

@Service("studentService")

publicclassStudentServiceImplimplementsStudentService{

@Resource

privateStudentMapper studentMapper;


@Override

publicListlistStudent(){

? ? ? ? List listStudent = studentMapper.listStudent();

returnlistStudent;

? ? }

}

     ? ?8)在student-service中創建數據層StudentMapper接口

packageorg.student.service.mapper;

importjava.util.List;

importorg.student.bean.Student;

publicinterfaceStudentMapper{

ListlistStudent();

}

     9)在student-web中創建實體映射的XML文件,注意StudentMapper類與sql ID的對應關系



? ? ? ? a.id,

? ? ? ? a.name,

? ? ? ? a.age



? ? ? ? SELECT

? ? ? ? FROM

? ? ? ? student a

     dubbo提供者已創建完成,創建完成子應用結構為

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

同時pom.xml中需要增加對的依賴

com.student.demo

student-api

1.0.0-SNAPSHOT

student-registry-address=172.0.0.1:2181

student-service-group=student-min

student-service-version=1.0.0

student-service-timeout=120000

2)spring-dubbo-consumer.xml的配置及接口調用方式


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">




group="${student-service-group}"version="${student-service-version}"

check="false"/>


3)調用者的controller層

packageorg.student.controller;

importjavax.annotation.Resource;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.RequestMethod;

importorg.springframework.web.bind.annotation.RestController;

importorg.student.api.StudentApi;

@RestController

@RequestMapping("/student")

publicclassStudentController{

privatestaticLogger logger = LoggerFactory.getLogger(StudentController.class);

@Resource

privateStudentApi studentApi;


@RequestMapping(path ="/listStudent", method = RequestMethod.POST)

publicvoidlistStudent(){

logger.info("get students...");

logger.info("the data are "+ studentApi.listStudents());

? ? }

}

4)服務器同時啟動provider和consumer,會看到啟動信息

查看zookeeper注冊中心發現提供者消費者都已成功注冊

     5)測試接口

    由于我并沒有寫view層來展示數據,現在只能通過控制臺的日志信息來簡單測試接口。(logback的用法不做解釋)利用瀏覽器post請求訪問

http://172.0.0.1:8080/student-test/student/listStudent,控制臺輸出為

[http-nio-8080-exec-2] INFO2016-11-0718:33:24.450o.s.c.StudentController[24] - get students...

[DubboServerHandler-172.28.19.7:22026-thread-2] INFO2016-11-0718:33:24.729d.a.o.s.a.StudentApi[58] -? [DUBBO] [2016-11-0718: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] INFO2016-11-0718:33:25.026o.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.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中用配置(詳細配置請查看上文)再通過命令行:

mvninstall -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 文件中通過 進行定義 —— 也就是說,在 XML 配置文件中定義 Bean,通過@Autowired或@Resource為 Bean 的成員變量、方法入參或構造函數入參提供自動注入的功能。以前通過在spring文件中配置的方式被移除,僅需要添加一行 配置就解決所有問題了——Spring XML 配置文件得到了極致的簡化。 的 base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。解決:在spring-base.xml中添加

      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中配置

? ? ? ? contextConfigLocation? ? ? ? classpath:spring/spring-base.xml...


? ? ? ? dispatcher? ? ? ? org.springframework.web.servlet.DispatcherServlet? ? ? ? ? ? ? ? ? ? contextConfigLocation? ? ? ? ? ? classpath:spring/spring-dispatcher.xml? ? ? ? ? ? ? ? dispatcher? ? ? ? /

      在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配置了

      而在spring-dispatcher.xml中未配置掃描路徑。所以spring無法加載controller中的映射,自然會404了,解決方式則是在spring-dispatcher.xml中加上掃描。

1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,

需要突破技術瓶頸的可以加。

2、在公司待久了,過得很安逸,

但跳槽時面試碰壁。

需要在短時間內進修、跳槽拿高薪的可以加。

3、如果沒有工作經驗,但基礎非常扎實,對java工作機制,

常用設計思想,常用java開發框架掌握熟練的,可以加。

4、覺得自己很牛B,一般需求都能搞定。

但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加。

5.?群號:高級架構群?Java進階群:180705916 備注好信息!

6.阿里Java高級大牛直播講解知識點,分享知識,

多年工作經驗的梳理和總結,帶著大家全面、

科學地建立自己的技術體系和技術認知!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容