前言
为了跨出转型微服务的第一步,首先要基于spring boot搭建一个工程,这里就记录一下初始搭建服务的过程,以及其中遇到的问题。后续的计划是能够把微服务的一整套东西用到生产环境上去,细细想来好像难度不小。
依赖引入
spring boot可以使用maven进行项目管理,那第一选择肯定是使用maven无疑,那么需要先有一个maven工程就不说了,然后是根pom.xml中一些依赖的配置。
1 | <dependency> |
理论上来说一个不需要前端页面的web工程配置这些就够了。关于上述配置接下来要展开去说的有两点:
- 关于spring boot版本的选择,查阅了一些资料发现spring boot目前已经发布到2.x版本了,但是需要jdk1.8以上做为支持,而目前我们项目的生产环境还全线使用的jdk1.7,所以我优先考虑兼容老版本的项目,暂不使用2.0及以上版本。其实一开始选择的最接近2.0的1.5.15(SNAPSHOT)版本,但启动项目过程时报了如下错误:
1 | Exception in thread "main" java.lang.IllegalAccessError: tried to access method org.springframework.core.convert.support.DefaultConversionService.addCollectionConverters(Lorg/springframework/core/convert/converter/ConverterRegistry;)V from class org.springframework.boot.bind.RelaxedConversionService |
找了一篇博文里面有讲到类似的问题,说是版本之间兼容性造成的,将信将疑的将版本改成1.3.3.RELEASE之后还真的解决了问题,所以就暂时使用该版本了。
- 关于spring-boot-dependencies模块的配置,按照官方文档的说法Maven的用户可以通过继承spring-boot-starter-parent项目来获得一些合理的默认配置。这个parent提供了以下特性:(好几项其实没看懂,后面慢慢理解吧。。。)
1 | - 默认使用Java 8 |
但在实际开发中,往往模块需要定义自己的parent而,maven的pom.xml只允许一个parent的存在,此时就可以采用上述在根pom文件中配置spring-boot-dependencies的方式代替。
代码实现
代码实现非常简单,这个demo没有集成中间件,严格来说就是简单与springMVC进行了集成,文件结构仍然是src/main/java、src/main/resources、src/test/java、src/test/resources的老四样,src/main/java中的controller实现如下:
1 |
|
可以看到与一般的spring工程没有差多,最大的不同应该是体现在启动类Application中,代码片段如下:
1 |
|
此处不需要做任何xml的配置,仅需要定义application.properties文件或者application.yml,而本例中没有任何外部配置因此放一个空配置文件即可。
eclipse中配置完成后,run as的菜单下会有spring boot app的选项,点击即可运行。
默认通过http://localhost:8080/访问。
补充的问题
- 项目启动时有遇到如下问题:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/beans/factory/ListableBeanFactory
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.neo.HelloApplication.main(HelloApplication.java:10)
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.ListableBeanFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 13 more
报的是找不到ListableBeanFactory类的异常,查了一下发现ListableBeanFactory类位于spring-beans包中,于是单独引入了spring-beans包后错误消失了。个人猜测还是和spring boot的版本有关系。
2.修改项目结构后启动工程,调用接口报如下错误:
1 | This application has no explicit mapping for /error, so you are seeing this as a fallback |
发现原因为application类的放置位置不对,spring boot会自动加载启动类所在包下及其子包下的所有组件,因此一般要将application类放在最外层的目录中,而这次工程结构的修改恰好不符合这个规则,由此造成上述问题。
思考和总结
本篇只是实现了最简单的一个demo,根据线上的项目情况如果需要引入spring boot还要整合mybatis、mysql、redis、activeMq、quartz、netty、zookeeper、dubbo等。并且spring boot目标是没有xml配置项,因此除了配置参数外,还要考虑定义在xml中的bean如何处理的问题。这么一想,前路真是任重而道远啊。