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

2021-05-18 03:28

阅读:436

标签:e30   sum   engine   组件   接口   技术分享   51cto   wait   efi   

一、Maven多模块项目的创建

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

    1.新建Maven项目

技术分享图片
2.选择项目存放路径后,选择创建一个简单的maven项目
3.技术分享图片
 3.填写GroupId和ArtifactId,注意选择或者填写版本号
 技术分享图片
点击完成后,建立好了student-demo项目。之后删除项目src目录,打开pom.xml将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-servicestudent-apistudent-webjunitjunit3.8.1test ` 在建成的项目student-demo上右键选择Maven Module后创建子项目student-api。 ![](http://i2.51cto.com/images/blog/201810/05/48c38faf2b4f5fa6394d6e02584afb16.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 填写子模块名字: ![](http://i2.51cto.com/images/blog/201810/05/327ae30560e54d6c28ae295fdabf5f20.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 项目类型选择: ![](http://i2.51cto.com/images/blog/201810/05/5e13b9ace8ba39c4603f9982f4fad43d.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)  点击完成,建立好第一个模块后,同样的过程建立好student-service模块和student-web模块,需要注意的是student-web选择的maven类型是: ![](http://i2.51cto.com/images/blog/201810/05/5ad6ad252c38aa746b26f7939f7cc90e.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 修改子模块项目目录中的pom.xml文件,把XXX1.0.0-SNAPSHOT去掉,加上jar,因为groupId和version会继承student-demo中的groupId和version,packaging设置打包方式为jar。例如修改后的student-service模块的pom.xml如下: ``` 4.0.0com.student.demostudent-demo1.0.0-SNAPSHOTstudent-servicejar ``` 至此,maven多模块项目已经创建完成,现在我们需要在student-demo项目的pom中增加标签定义可被子项目继承的第三方依赖包,打包配置,资源插件等,同时注意统一定义依赖的版本,避免冲突。这里还利用Maven配置了profiles,可根据情况增加不同的运行环境,并方便快捷地切换项目运行环境,目前我们只设置了dev开发环境。 ``` 4.0.0com.student.demostudent-demo1.0.0-SNAPSHOTpomUTF-81.16.101.0.15.1.214.2.5.RELEASE3.3.01.3.04.1.61.5.41.8.03.1.01.4.63.20.0-GA2.71.4.22.2.415.01.7.211.1.71.2.121.7.50.1.22.5.33.4.80.83.11.9.121.2.32.3.221.9.24.111.10.192.9.34.14.5.21.2.112.72.5.13.0.01.14.8.01.8UTF-8${project.artifactId}src/profiles2.6.0student-servicestudent-apistudent-weborg.hibernatehibernate-validator5.2.4.Finalorg.springframeworkspring-core${dep.ver.springframework}commons-loggingcommons-loggingorg.springframeworkspring-context${dep.ver.springframework}org.springframeworkspring-context-support${dep.ver.springframework}org.springframeworkspring-web${dep.ver.springframework}org.springframeworkspring-webmvc${dep.ver.springframework}org.springframeworkspring-jdbc${dep.ver.springframework}org.springframeworkspring-tx${dep.ver.springframework}org.springframeworkspring-aspects${dep.ver.springframework}com.alibabadruid${dep.ver.druid}mysqlmysql-connector-java${dep.ver.mysql}org.mybatismybatis${dep.ver.mybatis}org.mybatismybatis-spring${dep.ver.mybatis-spring}com.github.pagehelperpagehelper${dep.ver.pagehelper}org.apache.commonscommons-lang3${dep.ver.commons-lang3}commons-beanutilscommons-beanutils${dep.ver.commons-beanutils}commons-loggingcommons-loggingorg.slf4jslf4j-api${dep.ver.slf4j}org.slf4jlog4j-over-slf4j${dep.ver.slf4j}org.slf4jjcl-over-slf4j${dep.ver.slf4j}ch.qos.logbacklogback-classic${dep.ver.logback}com.alibabadubbo${dep.ver.dubbo}springorg.springframeworknettyorg.jboss.nettyorg.apache.zookeeperzookeeper${dep.ver.zookeeper}log4jlog4jcom.101teczkclient${dep.ver.zkclient}log4jlog4jorg.codehaus.jacksonjackson-core-asl${dep.ver.jackson}org.codehaus.jacksonjackson-mapper-asl${dep.ver.jackson}aspectjaspectjrt${dep.ver.aspectjrt}org.aspectjaspectjweaver${dep.ver.aspectjweaver}javax.servletjavax.servlet-api${dep.ver.servlet}providedorg.javassistjavassist${dep.ver.javassist}junitjunit${dep.ver.junit}testorg.springframeworkspring-test${dep.ver.springframework}testorg.mockitomockito-core${dep.ver.mockito}testcom.google.code.gsongson${dep.ver.gson}com.google.guavaguava${dep.ver.guava}org.projectlomboklombok${dep.ver.lombok}org.apache.commonscommons-collections4${dep.ver.commons-collections4}org.apache.httpcomponentshttpclient${dep.ver.httpclient}commons-loggingcommons-logginglocal${profiles.dir}/localdev${profiles.dir}/dev${center.project.name}org.apache.maven.pluginsmaven-resources-plugin${plg.ver.maven-resources-plugin}${encoding}org.apache.maven.pluginsmaven-compiler-plugin${plg.ver.maven-compiler-plugin}${jdk.ver}${jdk.ver}${encoding}maven-source-plugin${plg.ver.maven-source-plugin}truecompilejarsrc/main/resourcestrue ``` 在student-api中继承父pom的依赖,并且直接引入。 ``` 4.0.0com.student.demostudent-demo1.0.0-SNAPSHOTstudent-apicom.alibabafastjson${dep.ver.fastjson}org.springframeworkspring-contextorg.springframeworkspring-weborg.apache.httpcomponentshttpclientcom.google.code.gsongsoncom.google.guavaguava ``` 在student-service中添加继承依赖,添加对student-api的依赖。 ``` 4.0.0com.student.demostudent-demo1.0.0-SNAPSHOTstudent-servicecom.student.demostudent-api1.0.0-SNAPSHOTcom.alibabafastjson${dep.ver.fastjson}com.aliyun.ossaliyun-sdk-oss2.0.7commons-loggingcommons-loggingcom.alibabadruidmysqlmysql-connector-javaorg.mybatismybatisorg.mybatismybatis-springcom.github.pagehelperpagehelperorg.springframeworkspring-coreorg.springframeworkspring-contextorg.springframeworkspring-webmvcorg.springframeworkspring-jdbcorg.springframeworkspring-context-supportorg.springframeworkspring-txorg.springframeworkspring-aspectscom.fasterxml.jackson.corejackson-core${jackson.version}com.fasterxml.jackson.corejackson-databind${jackson.version}com.fasterxml.jackson.corejackson-annotations${jackson.version}org.slf4jslf4j-apich.qos.logbacklogback-classicorg.slf4jlog4j-over-slf4jorg.slf4jjcl-over-slf4jcom.google.guavaguavaorg.apache.commonscommons-lang3commons-beanutilscommons-beanutilsjavax.servletjavax.servlet-apiorg.javassistjavassistaspectjaspectjrtorg.aspectjaspectjweavercom.alibabadubbospringorg.springframeworknettyorg.jboss.nettyorg.apache.zookeeperzookeeperorg.slf4jslf4j-log4j12com.101teczkclientorg.slf4jslf4j-log4j12org.apache.httpcomponentshttpclientcglibcglib3.1 ``` 在student-web中继承依赖,添加对student-api,student-service的依赖。注意子项目依赖版本都为1.0.0-SNAPSHOT ``` 4.0.0com.student.demostudent-demo1.0.0-SNAPSHOTstudent-webwarjunitjunitcom.student.demostudent-api1.0.0-SNAPSHOTcom.student.demostudent-service1.0.0-SNAPSHOTstudent-web ```  ``` 二、Maven与SpringMVC的整合     1.第一部分已经在项目pom文件中配置了spring的相关依赖     2.在student-web项目根路径上添加profiles源目录及配置文件      注意是建立源文件不是普通文件夹。 ![](http://i2.51cto.com/images/blog/201810/05/96b9760744060b7d6b66c5f6194e3386.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)   然后在此源文件夹下建立普通文件夹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数据表,其结构为: ![](http://i2.51cto.com/images/blog/201810/05/a16325b0a1302b26737c5d35d0452b01.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 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中的内容为: ``` classpath:props/db-config.properties ```   同样DispatcherServlet会从classpath:spring/spring-dispatcher.xml加载它的bean。 ``` ```  4.在Web.xml中声明DispatcherServlet   SpringMVC所有请求都会通过一个前端控制器DispatcherServlet,通过这个控制器将请求委托给应用程序的其它执行单元来处理,所以需要通过web.xml来注册。打开student-web项目目录下src/main/webapp/WEB-INF/web.xml,修改web.xml `student-webcontextConfigLocationclasspath:spring/spring-base.xmlorg.springframework.web.context.ContextLoaderListenercharacterEncodingFilterorg.springframework.web.filter.CharacterEncodingFilterencodingUTF-8forceEncodingtruecharacterEncodingFilter/*dispatcherorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:spring/spring-dispatcher.xmldispatcher/ `  5.spring与Mybatis的整合      在student-web的src/main/resources目录中新建mybatis文件夹,再在此目录新建mybatis.xml和mapper文件夹。在spring文件夹下新建spring-db.xml用于spring加载mybatis配置。spring-db.xml内容如下: ``` ```  三、Dubbo的环境配置及与整合      我们已经搭建好student-demo项目来作为provider,为其它服务提供接口,所以我们需要先配置好dubbo提供者,PS:这里不会讲解zookeeper的搭建,请自行百度。其项目结构为: ![](http://i2.51cto.com/images/blog/201810/05/6224144b75871536bd5a5b791ce34cd1.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 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 ``` ``` 2.写一个简单的服务接口 1)首先在student-service中建立Student实体类 ``` package org.student.bean; public class Student { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ```  2)同时在student-api中建立与实体bean对应的DTO类实现Serializable接口,并重写toString方法。一般为了不破坏实体类和数据库表一一对应的接口,我们会新建一个DTO实体类,并且加入一些冗余的字段,作为前后端的传输对象。 `package org.student.api.dto; import java.io.Serializable; public class StudentDTO implements Serializable{ private static final long serialVersionUID = 1L; private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "id = " + id + ", name = " + name + ",age = " + age; } } ` 3)在student-api中建立StudentApi接口,值得注意的是@service注解中的对象 ``` package org.student.api; import java.util.List; import org.student.api.dto.StudentDTO; public interface StudentApi { List listStudents(); } ``` 4)在dubbo-producer.xml中注册StudentApi,添加配置: ``` ``` 5)从service业务逻辑层子模块开始编写接口实现,新建在student-service中新建StudentBiz实现StudentApi接口 ``` package org.student.service.biz; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.student.api.StudentApi; import org.student.api.dto.StudentDTO; import org.student.bean.Student; import org.student.service.StudentService; import com.google.common.collect.Lists; @Service("studentApi") public class StudentBiz implements StudentApi{ private Logger logger = LoggerFactory.getLogger(StudentBiz.class); @Autowired private StudentService studentService; @Override public List listStudents() { List listStudent = studentService.listStudent(); List listStudentDTO = Lists.newArrayList(); for(Student student: listStudent){ StudentDTO studentDTO = new StudentDTO(); studentDTO.setId(student.getId()); studentDTO.setAge(student.getAge()); studentDTO.setName(student.getName()); listStudentDTO.add(studentDTO); } return listStudentDTO; } } ``` 6)在student-service中创建service层接口StudentService ``` package org.student.service; import java.util.List; import org.springframework.stereotype.Service; import org.student.bean.Student; @Service public interface StudentService { List listStudent(); } ``` 7)在student-service中实现StudentService接口 ``` package org.student.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.student.bean.Student; import org.student.service.StudentService; import org.student.service.mapper.StudentMapper; @Service("studentService") public class StudentServiceImpl implements StudentService{ @Resource private StudentMapper studentMapper; @Override public List listStudent() { List listStudent = studentMapper.listStudent(); return listStudent; } } ``` 8)在student-service中创建数据层StudentMapper接口 ``` package org.student.service.mapper; import java.util.List; import org.student.bean.Student; public interface StudentMapper { List listStudent(); } ``` 9)在student-web中创建实体映射的XML文件,注意StudentMapper类与sql ID的对应关系 ``` a.id, a.name, a.age ``` dubbo提供者已创建完成,创建完成子应用结构为 ![](http://i2.51cto.com/images/blog/201810/05/38133a6fc5887883303f656cc7c75262.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) ![](http://i2.51cto.com/images/blog/201810/05/8edd9206e589c67c1db1edd288145f22.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) ![](http://i2.51cto.com/images/blog/201810/05/c7d5c09943dbe6e16f773370a81426d9.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 1)dubbo-consumer.properties的service-group应该与提供者一致,否者找不到提供者方的接口。 ![](http://i2.51cto.com/images/blog/201810/05/e54ff24be530394046e11558cb3c8e54.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 同时pom.xml中需要增加对的依赖 ``` com.student.demostudent-api1.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的配置及接口调用方式 ` ` 3)调用者的controller层  ``` package org.student.controller; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.student.api.StudentApi; @RestController @RequestMapping("/student") public class StudentController { private static Logger logger = LoggerFactory.getLogger(StudentController.class); @Resource private StudentApi studentApi; @RequestMapping(path = "/listStudent", method = RequestMethod.POST) public void listStudent(){ logger.info("get students..."); logger.info("the data are " + studentApi.listStudents()); } } ``` 4)服务器同时启动provider和consumer,会看到启动信息 ![](http://i2.51cto.com/images/blog/201810/05/56791e270cc6c614a5dfbe94aae16d2e.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) ``` 查看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.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中用配置(详细配置请查看上文)再通过命令行: `mvn install -Pdev #激活dev环境` 也可以通过eclipse的配置:项目-->properties-->Maven-->填写profile名-->apply-->finish ![](http://i2.51cto.com/images/blog/201810/05/58e9a632ee8dba69bf47d1b19d355eeb.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 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保持一致 ![](http://i2.51cto.com/images/blog/201810/05/6c6e7a776d493508d49fb3fe5cdc9d07.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 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中配置 ` contextConfigLocationclasspath:spring/spring-base.xml ... dispatcherorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:spring/spring-dispatcher.xmldispatcher/ `  在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中加上扫描。

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

标签:e30   sum   engine   组件   接口   技术分享   51cto   wait   efi   

原文地址:http://blog.51cto.com/13981400/2293965


评论


亲,登录后才可以留言!