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高级大牛直播讲解知识点,分享知识,

多年工作经验的梳理和总结,带着大家全面、

科学地建立自己的技术体系和技术认知!

推荐阅读更多精彩内容