前言
为了跨出转型微服务的第一步,首先要基于spring boot搭建一个工程,这里就记录一下初始搭建服务的过程,以及其中遇到的问题。后续的计划是能够把微服务的一整套东西用到生产环境上去,细细想来好像难度不小。
依赖引入
spring boot可以使用maven进行项目管理,那第一选择肯定是使用maven无疑,那么需要先有一个maven工程就不说了,然后是根pom.xml中一些依赖的配置。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
理论上来说一个不需要前端页面的web工程配置这些就够了。关于上述配置接下来要展开去说的有两点:
- 关于spring boot版本的选择,查阅了一些资料发现spring boot目前已经发布到2.x版本了,但是需要jdk1.8以上做为支持,而目前我们项目的生产环境还全线使用的jdk1.7,所以我优先考虑兼容老版本的项目,暂不使用2.0及以上版本。其实一开始选择的最接近2.0的1.5.15(SNAPSHOT)版本,但启动项目过程时报了如下错误:
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
at org.springframework.boot.bind.RelaxedConversionService.<init>(RelaxedConversionService.java:52)
at org.springframework.boot.bind.RelaxedDataBinder.modifyProperties(RelaxedDataBinder.java:148)
at org.springframework.boot.bind.RelaxedDataBinder.doBind(RelaxedDataBinder.java:128)
at org.springframework.validation.DataBinder.bind(DataBinder.java:691)
at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:269)
at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:241)
at org.springframework.boot.context.config.ConfigFileApplicationListener.bindToSpringApplication(ConfigFileApplicationListener.java:230)
at org.springframework.boot.context.config.ConfigFileApplicationListener.postProcessEnvironment(ConfigFileApplicationListener.java:181)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ConfigFileApplicationListener.java:166)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent(ConfigFileApplicationListener.java:152)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:119)
at org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:111)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:65)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:329)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
at com.neo.HelloApplication.main(HelloApplication.java:10)
找了一篇博文里面有讲到类似的问题,说是版本之间兼容性造成的,将信将疑的将版本改成1.3.3.RELEASE之后还真的解决了问题,所以就暂时使用该版本了。
- 关于spring-boot-dependencies模块的配置,按照官方文档的说法Maven的用户可以通过继承spring-boot-starter-parent项目来获得一些合理的默认配置。这个parent提供了以下特性:(好几项其实没看懂,后面慢慢理解吧。。。)
- 默认使用Java 8
- 使用UTF-8编码
- 一个引用管理的功能,在dependencies里的部分配置可以不用填写version信息,这些version信息会从spring-boot-dependencies里得到继承。
- 识别资源过滤(Sensible resource filtering.)
- 识别插件的配置(Sensible plugin configuration (exec plugin, surefire, Git commit ID, shade).)
- 能够识别application.properties和application.yml类型的文件,同时也能支持profile-specific类型的文件(如: application-foo.properties and application-foo.yml,这个功能可以更好的配置不同生产环境下的配置文件)。
- maven把默认的占位符${…}改为了@..@
但在实际开发中,往往模块需要定义自己的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实现如下:
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Hello Spring Boot!";
}
}
可以看到与一般的spring工程没有差多,最大的不同应该是体现在启动类Application中,代码片段如下:
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
此处不需要做任何xml的配置,仅需要定义application.properties文件或者application.yml,而本例中没有任何外部配置因此放一个空配置文件即可。
eclipse中配置完成后,run as的菜单下会有spring boot app的选项,点击即可运行。
默认通过http://localhost:8080/访问。
补充的问题
项目启动时有遇到如下问题:
Exception 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的版本有关系。
思考和总结
本篇只是实现了最简单的一个demo,根据线上的项目情况如果需要引入spring boot还要整合mybatis、mysql、redis、activeMq、quartz、netty、zookeeper、dubbo等。并且spring boot目标是没有xml配置项,因此除了配置参数外,还要考虑定义在xml中的bean如何处理的问题。这么一想,前路真是任重而道远啊。
网友评论