Migrate spring project to spring-boot

基礎背景

基於主流發展趨勢向着基於spring-boot, 在其基礎上開發配套的開箱即用項目, 和與其緊密結合的獨立項目發展.且spring5已經出現了很長時間, 雖然SSM的經典搭配可以滿足需求, 但決定要將個人的項目升級到spring-boot+spring5的搭配上.畢竟公司實在沒有合適的讓我下刀, 逃;)

調研

截至我寫這篇博客, spring-boot最新的版本是2.2.0, 使用idea的Spring Initializr即可新建一個spring boot項目. 我在這裏遇到了一個問題, 如果使用了spring-boot-start-web這個包, 並繼承了父文件的版本(即2.2.0), 那麼由其引入的依賴:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.10.0</version>
</dependency>

會下載失敗, 即使下載成功, 在idea中解析的時候也會失敗, 導致idea不能自動引入外部依賴jar包, 表現爲項目的主啓動類import語句報錯, pom.xml文件也會有錯誤提示. 我在同事的電腦上也嘗試了直接引入jackson-annotations這個包的2.10.0版本, 結果也報錯不能下載. 目前我的解決方案是在spring-boot-start-web中排除掉了jackson-annotations的引用, 直接引用其上一個版本2.9.9,如下:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.9</version>
</dependency>
​
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
    </exclusions>
</dependency>

爲了方便, 我使用舊後臺與新後臺, 分別指代原使用SSM的項目與遷移後使用springboot的項目.

<!-- more -->

下手

整體遷移的核心路線是: 框架正常啓動 -> web接口 -> 數據庫訪問 -> 整體業務部分 -> 靜態頁面文件

web接口部分

項目中有使用swagger作爲api文檔支持, 因此我先放棄了對自己編寫的頁面文件的移植, 通過swagger的頁面來測試, 是否已經使web部分生效.

舊後臺的 controller 層, 使用了 @controller 註解來標識類爲一個controller, 並在方法的返回值上, 添加了 @ResponseBody註解來返回json字符串. 在新項目中替換爲@RestController註解, 此註解爲一個複合註解, 源碼如下:

@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

兼具了@Controller@ResponseBody的作用.

整體swagger的測試controller代碼如下:

@RestController
@RequestMapping("/test")
@Api(value = "testSwaggerController", description = "測試swagger2集成結果.")
public class TestController {
    @RequestMapping("testMe")
    @ApiOperation(value = "測試接口", httpMethod = "POST", response = String.class, notes = "測試swagger2 api用.")
    public String test(
            @ApiParam(name = "name", type = "String", value = "訪問者姓名")
            @RequestParam(value = "name", required = false) String name,
            HttpServletRequest request, HttpServletResponse response){
        String _name = name == null ? "匿名者" : name;
        response.setContentType("text/plain;charset=UTF-8");
        return "hello,Tester " + _name + ".I get your IP is:" + IP_util.getIpAddr(request);
    }}
​

舊項目使用的xml配置文件的方式, 定義了mvc靜態資源, 以使swagger靜態頁面可以被訪問. 在springboot中, 雖然可以通過引入xml配置文件的方式(通過@ImportResource註解)達到同樣的目的, 但我選擇了另外一種基於java配置的方式.

此方法通過實現WebMvcConfigurer接口, 重寫addResourceHandlers方法, 註冊新的靜態資源路徑, 達到的效果是一樣的.代碼如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {
​
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/statics/**").addResourceLocations("classpath:/statics/");
        // 解決 SWAGGER 404報錯
        registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

swagger 的配置類如下:

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
​
    @Bean
    public Docket api() {
        //swagger-ui 上的response content type 下拉選擇, 填充上 image/jpeg之後, 可以支持對圖片請求的模擬
        return new Docket(DocumentationType.SWAGGER_2)
                .produces(Sets.newHashSet("*/*", "image/jpeg"))
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("cn.codeh.blogbackground"))
                .build();
​
    }
​
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("blog API")
                .description("blog API doc.")
                .termsOfServiceUrl("https://codeh.cn/")
                .version("1.0")
                .build();
    }
​
}

至此, swagger的重點配置已經完畢. 啓動XApplication類的main方法, 在瀏覽器中訪問http://127.0.0.1:8080/swagger-ui.html, 即可看到熟悉的綠色界面了.

數據庫訪問部分

首先, 添加依賴.

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

由於我的項目之前使用的是xml編寫的mappers文件, 因此就不再使用註解的方式改造了, 所幸通過xml的配置方式支持很好, 只需要少量的配置就可以使用.

appcalition.yml(就是你的springboot主要配置文件)中添加如下配置.

spring:
  datasource:
    url: 'jdbc:mysql://123.123.123.123:123/test?characterEncoding=utf-8'
    username: test
    password: '123456'
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mybatis/mappers/*.xml
  config-location: classpath:mybatis/config/mybatis-config.xml

如果是properties文件, 則需要擴展key至全稱, 官方推薦使用yml, 我也就改了, 其實坑比較多, 例如密碼如果是純數字, 000會變成0, 因爲yml中有類型. 選擇自己習慣的即可.

如上配置後, 我複製所有的mapper文件到新項目中, 通過mapper-locations指定位置. 主要配置文件通過config-location指定.

在XAppcalition類中添加註解@MapperScan("xxx.xxx.xxx")用以指定Mapper的interface文件路徑.

如果使用idea, 那麼在service中使用

@Autowired
private Mapper mapper;

類似這樣的自動注入時, 可能會報找不到類的問題, 解決方案是在interface文件中, 添加@Repository註解. 當然不加的話項目也不會報錯, 只是看到一條報錯的紅線, 總是不爽.

整體業務部分

這部分其實沒什麼好說的, controller和數據庫部分都可以正常使用了, 剩下的只要按照之前的樣子copy過去即可.

靜態資源部分

springboot默認會將以下目錄作爲靜態資源的放置路徑:

classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources

因此, 我只需要將原有項目的webapps目錄下的文件悉數移動到static目錄下即可.

結束

至此, 我的遷移工作已經全部結束, 本文斷斷續續的寫了幾天, 其實每個部分都有很多的知識點可以深入研究, 但目的是首先讓它運行起來. 希望我記錄的過程對你會有幫助.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章