当前位置: 移动技术网 > IT编程>开发语言>Java > 从SpringMVC迁移到Springboot的方法步骤

从SpringMVC迁移到Springboot的方法步骤

2019年07月19日  | 移动技术网IT编程  | 我要评论
在将springmvc项目转移到springboot上的过程中,主要做了以下的事情 profile配置 全局变量从properties文件读入 数据源

在将springmvc项目转移到springboot上的过程中,主要做了以下的事情

  1. profile配置
  2. 全局变量从properties文件读入
  3. 数据源与mybatis配置
  4. 日志文件配置
  5. webconfig配置(包括原有的web.xml和spring-mvc.xml)
  6. 去掉多余的bean注入

本篇文章除了介绍做了些什么和怎么做之外,会多很多多余的废话,关于对原理的一些探讨,知其然也要知其所以然。

profile配置

在传统的spring项目中,多个profile的配置方式首先是在pom.xml文件中写入多个profile,再通过启动项目前先执行一个maven文件来预加载选定的profile环境。加载完之后,执行项目的时候,会根据已加载的environment,来决定去将哪个.properties文件load到全局变量中。

而在springboot中对多个profile的管理就非常简单了。

可以在jar包用命令行运行时选择profile

java -jar example.jar --spring.profiles.active=test

或者在application.properties这个全局配置中配置

在application.properties中添加spring.profiles.active=test

以上两种方法均可启动“test"这个profile,前者在执行上的优先级要高于后者。

(顺便一提,在springboot里面,这两种方式本质上都是用“外部化配置”的方式,来对environment进行编辑和替换)

另外,每个独立的profiles的配置方式为以"application-xxx.properties"格式,针对每个不同环境,例如:

  1. application-pro.properties 表示预演环境
  2. application-dev.properties 表示开发环境
  3. application-test.properties 表示测试环境

当我们需要测试是否正常载入了profile的时候,可以在对应的.properties文件中写入

server.port=9080

在启动的时候就可以看到,是否已经启动了这个端口。

在这里可以顺便提一下springboot加载配置文件的顺序

  1. home目录下的devtools全局设置属性( ~/.spring-boot-devtools.properties ,如果devtools激活)。
  2. 测试用例上的@testpropertysource注解。
  3. 测试用例上的@springboottest#properties注解。
  4. 命令行参数
  5. 来自 spring_application_json 的属性(环境变量或系统属性中内嵌的内联json)。
  6. servletconfig 初始化参数。
  7. servletcontext 初始化参数。
  8. 来自于 java:comp/env 的jndi属性。
  9. java系统属性(system.getproperties())。
  10. 操作系统环境变量。
  11. randomvaluepropertysource,只包含 random.* 中的属性。
  12. 没有打进jar包的profile-specific应用属性( application-{profile}.properties 和yaml变量)。
  13. 打进jar包中的profile-specific应用属性( application-{profile}.properties 和yaml变量)。
  14. 没有打进jar包的应用配置( application.properties 和yaml变量)。
  15. 打进jar包中的应用配置( application.properties 和yaml变量)。
  16. @configuration 类上的 @propertysource 注解。
  17. 默认属性(使用 springapplication.setdefaultproperties 指定)。

全局变量从properties文件读入

在上一面一小节写了针对不同环境的properties配置,这里会写关于如果将这些属性写入到全局变量中,方便后面其他地方直接调用。

/**
 * 全局变量
 */
public class global {

 public static string examplepath;

 @value("${example_path}")
  public void setexamplepath(string example) {
    global.examplepath = examplepath;
  }
}

通过这样子,我们便将.properties文件中的

example_path=http://localhost:9090

这个属性读到了全局变量中。

数据源与mybatis配置

在传统的spring项目中,用mybatis连接数据库

  1. 首先要创建一个名为datasource的bean
  2. 然后将这个datasource装配到sqlsessionfactory中
  3. 最后再将sqlsessionfactory装配到mapperscannerconfigurer中

这一切都是在xml配置文件中配置的,比较繁琐。在springboot中会尽量去避免这样子的xml配置。
mybatis现在已经为springboot提供了支持,我们只需要添加mybatis-spring-boot-starter这个依赖,它就会为我们去做好以下的事情:

  1. 自动检测已有的datasource
  2. 创建一个sqlsessionfactorybean的实例sqlsessionfactory,并将datasource装配进去
  3. 创建一个sqlsessiontemplate的实例,并将sqlsessionfactory装配进去
  4. 自动扫描你的mapper,将它们连接到sqlsessiontemplate,并将它们注册到spring的上下文,以便将它们注入到其他的bean中。

所以,在springboot的mybatis配置中,我们需要去做以下几件事情:

在application-{profile}.properties中填入数据库信息,例如:

spring.datasource.url=jdbc:oracle:thin:@//localhost:1234/example
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=oracle.jdbc.driver.oracledriver
spring.datasource.maxactive=10
spring.datasource.maxidle=5
spring.datasource.maxwait=-1

通过这种方式,我们便在spring上下文中注册了datasource这个bean。

创建一个mybatisconfig文件,用java的方式取代xml:

/**
 * created by wutaoyu on 2017/12/7.
 */
@configuration
@enabletransactionmanagement
@mapperscan("com.example.db.dao")
public class mybatisconfig {

  @autowired
  private datasource datasource;

  @bean(name = "sqlsessionfactory")
  public sqlsessionfactory sqlsessionfactorybean() {
    sqlsessionfactorybean sqlsession = new sqlsessionfactorybean();
    sqlsession.setdatasource(datasource);
    try {
      //添加xml目录
      resourcepatternresolver resolver = new pathmatchingresourcepatternresolver();
      sqlsession.setmapperlocations(resolver.getresources("classpath:mapping/*.xml"));
      return sqlsession.getobject();
    } catch (exception e) {
      e.printstacktrace();
      throw new runtimeexception(e);
    }
  }

  @bean
  public sqlsessiontemplate sqlsessiontemplate(sqlsessionfactory sqlsessionfactory) {
    return new sqlsessiontemplate(sqlsessionfactory);
  }

  @bean
  public platformtransactionmanager annotationdriventransactionmanager() {
    return new datasourcetransactionmanager(datasource);
  }


  @bean(name = "examplesequence")
  public oraclesequencemaxvalueincrementer examplesequencebean(){
    oraclesequencemaxvalueincrementer examplesequence = new oraclesequencemaxvalueincrementer();
    examplesequence.setincrementername("example_seq");
    examplesequence.setdatasource(datasource);
    return examplesequence;
  }
}

@mapperscan是扫描这个包下面的mapper。

另外这里mapper.xml的位置,是在resource文件夹下面建了一个mapping文件夹,放在下面。

这里的作用跟xml比较类似,是将传统的xml表达方式用.java文件来描述出来,本质上还是将datasource一步步注入。

由于示例用的是oracle数据库,所以最后一个examplesequence是示范如何添加序列。

对所有mapper的interface注解@mapper

例如:

@mapper
public interface usermapper {
 ...
}

日志文件配置

logback支持用properties的方式外部化配置,但是对于比较细的配置来说,还是要沿用xml配置。

为了让xml文件从.properties文件读取一些路径之类可能需要经常修改的静态配置,需要在logback-spring.xml中配置

 <property resource="application.properties" />
  <property name="log.root.level" value="${log.root.level}" />
  <property name="log.path" value="${log.path}" />
  <property name="log.modulename" value="${log.module}" />

这样子就可以将application.properties文件中的

log.path=/home/logs/example
log.root.level=info
log.module=example

读入到logback-spring.xml中,然后再去调用。

webconfig配置

webconfig的主要作用是替代web.xml和spring-mvc.xml进行一些基础配置。

1、关于web.xml

传统的spring项目都有配置一个web.xml文件,这个文件的作用是:当我们把war包放入应用容器(例如tomcat)中运行时,容器会根据web.xml去加载filter(过滤器)、servlet、error-page、welcome-file-list、listener(监听器)、context-param(上下文参数)、resource-ref(资源配置)等配置。

包括contextloaderlistener这个监听器,就是在这里加载进去,用于在启动容器的时候,自动装配applicationcontext的配置信息。

<listener>
<listener-class>org.springframework.web.context.contextloaderlistener</listener-class>
</listener>

这个applicationcontext是spring ioc的核心(继承自beanfactory),所有单例的bean会在这个时候就被实例化。
以及,springmvc中很重要的一个dispatcherservlet也是在这里加载进去,并制定根据哪个xml文件来配置dispatcherservlet。

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
    <init-param>
      <param-name>contextconfiglocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <!--<async-supported>true</async-supported>-->
</servlet>

2、关于spring-mvc.xml

spring-mvc.xml是springmvc的配置文件,在这里可以配置我们引入的、需要定制化的bean,例如viewresolver、multipartresolver、http消息转换器、自定义的拦截器等等。

以上都与springboot无关,主要是为了知其然也知其所以然,如果不感兴趣的可以不看。

再讲回springboot的配置。springboot有一个说法叫“约定优于配置”,就是尽量用约定的方式,而不是特地去针对性地配置(需要特殊配置的时候再去配置)。

引入spring-boot-starter-web这个“开箱即用”的依赖之后,spring-boot-starter-web下包含了一个spring-boot-autoconfigure。
有了这个依赖之后,就可以使用@enableautocongiguration注解。这个注解就会根据引入的依赖来猜测你需要的spring配置并帮你配置好。因为已经引入了spring-boot-starter-web的话,这个注解就会将web相关的配置配置好。

另外,@springbootapplication这个注解中已经包含了@enableautocongiguration注解。所以只要在启动类exampleserverapplication上注解@springbootapplication就可以自动把web配置给配置好了。

当然,我们可能还有一些特殊的配置,这时候就可以创建一个webconfig去定制

/**
 * created by wutaoyu on 2017/12/8.
 */
@configuration
public class webconfig extends webmvcconfigureradapter {

  @override
  public void configuremessageconverters(list<httpmessageconverter<?>> converters) {
    converters.add(marshallinghttpmessageconverter());
  }

  public marshallinghttpmessageconverter marshallinghttpmessageconverter(){
    marshallinghttpmessageconverter marshallinghttpmessageconverter = new marshallinghttpmessageconverter();
    list<mediatype> mediatypes = new arraylist<mediatype>();
    mediatypes.add(mediatype.text_xml);
    mediatypes.add(mediatype.application_xml);
    xstreammarshaller xstreammarshaller=new xstreammarshaller();
    marshallinghttpmessageconverter.setsupportedmediatypes(mediatypes);
    marshallinghttpmessageconverter.setmarshaller(xstreammarshaller);
    marshallinghttpmessageconverter.setunmarshaller(xstreammarshaller);
    return marshallinghttpmessageconverter;
  }
  //配置文件上传
  @bean(name = {"multipartresolver"})
  public multipartresolver multipartresolver(){
    commonsmultipartresolver commonsmultipartresolver=new commonsmultipartresolver();
    commonsmultipartresolver.setdefaultencoding("utf-8");
    commonsmultipartresolver.setmaxuploadsize(10485760000l);
    commonsmultipartresolver.setmaxinmemorysize(40960);
    return commonsmultipartresolver;
  }
  //异常处理
  @bean
  public exceptionhandler exceptionresolver(){
    exceptionhandler exceptionhandler = new exceptionhandler();
    return exceptionhandler;
  }
  //拦截器
  @override
  public void addinterceptors(interceptorregistry registry){
    registry.addinterceptor(new loginterceptor()).addpathpatterns("/**");
    super.addinterceptors(registry);
  }
}

我写的这个示例文件里面做了几件事情:

  1. 引入一个xml的http消息转换器
  2. 引入multipartresolver
  3. 引入自定义的异常处理器
  4. 引入自定义拦截器

去掉多余的bean注入

这个算是一个题外话,但也是我实际遇到的问题之一。

在实际运行的springboot项目的时候,我发现了一些在传统spring项目中没有报错的问题,就是多余的bean注入。

在传统spring项目中,这是没有报错的,但是在springboot项目中就报错了。我猜测是因为要注入bean的类方法名取的比较精简的时候,与springboot本身自动配置的一些bean重复了,就会报错。

所以,把有些不需要注入的bean去掉吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网