欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

記一次Maven項(xiàng)目改造成SpringBoot項(xiàng)目的過程實(shí)踐

 更新時(shí)間:2022年03月09日 09:46:48   作者:白云漂  
本文主要介紹了Maven項(xiàng)目改造成SpringBoot項(xiàng)目的過程實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

背景概述

團(tuán)隊(duì)有一個(gè)項(xiàng)目,是maven構(gòu)建的普通Java項(xiàng)目。

項(xiàng)目沒有使用spring,用到了mysql、mybatis,還有其他大數(shù)據(jù)技術(shù),比如flink、pulsar。

項(xiàng)目里連接數(shù)據(jù)庫的部分,需要用到多個(gè)配置文件,一個(gè)是mybatis配置文件,一個(gè)是數(shù)據(jù)庫配置文件。如果用SpringBoot可以簡化為一個(gè)application.yml文件。

項(xiàng)目里打包方式復(fù)雜,依賴一個(gè)maven-assemble的插件,打出的包是兩個(gè)jar,出現(xiàn)過由于配置文件讀取方式的錯(cuò)誤,導(dǎo)致jar包還運(yùn)行不了。使用這個(gè)插件打包,還需要寫一個(gè)自定義的配置文件,配置各個(gè)資源打包的參數(shù)。如果用SpringBoot,直接引入spring-boot-maven-plugin,打出的就是可執(zhí)行jar包,不需要繁瑣的配置,不需要自己寫讀取配置的代碼。

為什么要改造成SpringBoot項(xiàng)目呢,因?yàn)镾pringBoot

  • 簡化配置,不用寫這么多配置文件
  • 自動(dòng)配置,引入starter依賴,可以自動(dòng)把默認(rèn)配置配好
  • 內(nèi)嵌web容器
  • 自動(dòng)版本管理,maven和starter配置使用
  • 生態(tài)集成容易,如果項(xiàng)目想要集成另外的能力,引一些starter依賴,少量的配置就可以快速接入

此外也是一次技術(shù)提升的機(jī)會(huì),技術(shù)的優(yōu)勢,SpringBoot早就熟爛了。 所以打算改造成SpringBoot項(xiàng)目。

過程

加依賴

改造過程一步步來, 先把SpringBootStarter引入進(jìn)來

<properties>
    <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- 此處省略其他的依賴 -->
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.12.RELEASE</version>
            <configuration>
                <mainClass>com.xxx.pulsar.PulsarMain</mainClass>
            </configuration>
            <executions>
                <execution>
                    <id>repackage</id>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

修改main方法所在類

在原先的main方法上加上注解

引入數(shù)據(jù)庫依賴

首先把main函數(shù)中配置的數(shù)據(jù)庫連接硬編碼刪除,后面將要使用application.yml來配置

<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.13</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

啟動(dòng)類上加入mapper掃描

@MapperScan("com.xxx.pulsar.mapper")

添加application.yml

# 端口
server:
  port: 8001

mybatis:
  # mapper映射文件
  mapper-locations: classpath:mapper/*.xml

spring:
  application:
    # 應(yīng)用名稱
    name: pulsar_demo
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driverClassName: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: 123456
      initial-size: 10
      max-active: 100
      min-idle: 10
      max-wait: 60000
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 60000
      max-evictable-idle-time-millis: 300000
      validation-query: SELECT 1 FROM DUAL
      # validation-query-timeout: 5000
      test-on-borrow: false
      test-on-return: false
      test-while-idle: true
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      #filters: #配置多個(gè)英文逗號(hào)分隔(統(tǒng)計(jì),sql注入,log4j過濾)
      filters: stat,wall
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*

sqlSessionFactory空指針異常分析

啟動(dòng)測試,報(bào)錯(cuò),數(shù)據(jù)庫連接的地方報(bào)sqlSessionFactory空指針異常

查看錯(cuò)誤堆棧,項(xiàng)目啟動(dòng)的時(shí)候,會(huì)從RuleFunction這個(gè)類的構(gòu)造函數(shù)里面開始初始化資源。

setFields和setExtInfo這兩個(gè)方法寫在構(gòu)造函數(shù)中,在類初始化時(shí),就會(huì)調(diào)用,從數(shù)據(jù)庫查初始化資源,

這兩個(gè)方法內(nèi)部會(huì)去查數(shù)據(jù)庫獲取基礎(chǔ)資源,見下圖

RuleFunction初始化時(shí),Spring還沒有幫我們將MybatisSessionFactory類實(shí)例化,所以報(bào)了空指針異常。

改造MybatisSessionFactory類

改造前的MybatisSessionFactory類代碼如下

public class MybatisSessionFactory {

    private volatile static SqlSessionFactory sqlSessionFactory;

    private MybatisSessionFactory() {}

    public static void init(String configStr, Properties prop) {
        if (sqlSessionFactory == null) {
            synchronized (MybatisSessionFactory.class) {
                if (sqlSessionFactory == null) {
                    InputStream is = new ByteArrayInputStream(configStr.getBytes());
                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(is, prop);
                }
            }
        }
    }

    public interface Action<RESULT, MAPPER> {
        RESULT action(MAPPER mapper);
    }

    public static <MAPPER, RESULT> RESULT query(Class<MAPPER> mapperClass, Action<RESULT, MAPPER> action) {
        if (sqlSessionFactory == null) {
            throw new NullPointerException("Mybatis未初始化");
        }
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            MAPPER mapper = sqlSession.getMapper(mapperClass);
            return action.action(mapper);
        }
    }

}

這個(gè)MybatisSessionFactory類,是在main方法中去初始化的,main方法中調(diào)用MybatisSessionFactory.init方法,傳入配置文件和配置參數(shù),從而初始化SqlSesstionFactory。

改造的過程中,我們把main方法中調(diào)用MybatisSessionFactory.init方法給刪除了,導(dǎo)致SqlSesstionFactory未初始化。

為什么不在main方法中調(diào)用MybatisSessionFactory.init,從而初始化SqlSesstionFactory?因?yàn)槲蚁Mㄟ^Spring注入和管理SqlSesstionFactory的對(duì)象。

在static工具類方法里調(diào)用Spring托管的bean對(duì)象[1]

這里遇到一個(gè)問題,注意SqlSessionFactory聲明方式上用了static關(guān)鍵字。即這個(gè)屬性是類的,不是對(duì)象的。生命周期比較早,在類初始化時(shí)就會(huì)初始化。

private volatile static SqlSessionFactory sqlSessionFactory;

我使用下面的方式,在MybatisSessionFactory類中加入下面代碼,并在MybatisSessionFactory類上加注解@Component。

@Autowired
private SqlSessionFactory sqlSessionFactory1;

@PostConstruct
public void update(){
    sqlSessionFactory = sqlSessionFactory1;
}
  • 首先使用@Autowired注入SqlSessionFactory
  • 使用@PostConstruct修飾update方法,方法名任意,不能有參數(shù)。這樣是為了保證這個(gè)順序:依賴注入之后,才執(zhí)行update方法。該注解的方法在整個(gè)Bean初始化中的執(zhí)行順序:Constructor(構(gòu)造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法)

RuleFunction類改造

還要改一個(gè)地方,初始化數(shù)據(jù)庫資源的入口方法是在RuleFunction類的構(gòu)造函數(shù)中調(diào)用的。由于構(gòu)造函數(shù)會(huì)先于依賴注入執(zhí)行,需要把setFields和setExtInfo這兩個(gè)方法提取出來,且需要在依賴注入后執(zhí)行。

修改成如下,并在RuleFunction類上加注解@Component。

改造前的執(zhí)行流程

  • main方法內(nèi)部調(diào)用MybatisSessionFactory的init方法
  • MybatisSessionFactory的init方法中new一個(gè)SqlSessionFactory
  • RuleFunction初始化時(shí),調(diào)用自身構(gòu)造方法
  • RuleFunction調(diào)用MybatisSessionFactory的query方法查詢數(shù)據(jù)庫

改造后的執(zhí)行流程

  • PulsarMain和MybatisSessionFactory是松耦合的,
  • MybatisSessionFactory初始化時(shí),因?yàn)橥ㄟ^@Autowired注解注入了SqlSessionFactory,所以需要初始化SqlSessionFactory,SqlSessionFactory初始化過程中會(huì)去使用配置文件中的數(shù)據(jù)庫連接參數(shù)初始化。
  • MybatisSessionFactory初始化完成后,由于MybatisSessionFactory.update方法使用了@PostConstruct注解,會(huì)執(zhí)行update方法,將SqlSessionFactory賦值給靜態(tài)屬性sqlSessionFactory。
  • 后續(xù)RuleFunction的setFields方法執(zhí)行過程中,就可以使用MybatisSessionFactory的query方法查詢數(shù)據(jù)庫了

總結(jié)

這次改造過程,對(duì)類加載過程、對(duì)象的實(shí)例化、static關(guān)鍵字、spring bean的生命周期有了更深入的理解。

  • 類加載過程,會(huì)初始化調(diào)用static修飾的屬性、方法、代碼塊
    • 類加載過程[2]:加載、鏈接、初始化
    • 其中鏈接的過程:驗(yàn)證、準(zhǔn)備、解析
  • 類初始化后,可以通過new關(guān)鍵字實(shí)例化一個(gè)對(duì)象,其它方式:通過反射api實(shí)例化
  • spring bean的生命周期[3]:實(shí)例化、屬性賦值、初始化、銷毀

擴(kuò)展

對(duì)于這個(gè)問題抽象一下:Spring項(xiàng)目中,如果需要在一個(gè)類初始化時(shí)加載數(shù)據(jù)庫資源,可以有哪些方式?

參考

到此這篇關(guān)于記一次Maven項(xiàng)目改造成SpringBoot項(xiàng)目的過程實(shí)踐的文章就介紹到這了,更多相關(guān)Maven改造成SpringBoot項(xiàng)目內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring security國際化及UserCache的配置和使用

    spring security國際化及UserCache的配置和使用

    這篇文章主要介紹下國際化的配置及UserCache的配置及使用教程,感興趣的朋友參考下實(shí)現(xiàn)代碼吧
    2017-09-09
  • Java中HashMap的初始容量設(shè)置方式

    Java中HashMap的初始容量設(shè)置方式

    這篇文章主要介紹了Java中HashMap的初始容量設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java Springboot websocket使用案例詳解

    Java Springboot websocket使用案例詳解

    這篇文章主要介紹了Java Springboot websocket使用案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • swing組件JScrollPane滾動(dòng)條實(shí)例代碼

    swing組件JScrollPane滾動(dòng)條實(shí)例代碼

    這篇文章主要介紹了swing組件JScrollPane滾動(dòng)條實(shí)例代碼,分享了兩個(gè)相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • mybatis中resultMap 標(biāo)簽的使用教程

    mybatis中resultMap 標(biāo)簽的使用教程

    resultMap 標(biāo)簽用來描述如何從數(shù)據(jù)庫結(jié)果集中來加載對(duì)象,這篇文章重點(diǎn)給大家介紹mybatis中resultMap 標(biāo)簽的使用,感興趣的朋友一起看看吧
    2018-07-07
  • SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過程

    SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過程

    分布式追蹤系統(tǒng)是一個(gè)最終的解決方案,如果您的公司已經(jīng)上了分布式追蹤系統(tǒng),這篇文章主要介紹了SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog,需要的朋友可以參考下
    2022-10-10
  • Spring事件監(jiān)聽基本原理與使用詳解

    Spring事件監(jiān)聽基本原理與使用詳解

    這篇文章主要介紹了Spring事件監(jiān)聽基本原理與使用詳解,Spring的事件監(jiān)聽機(jī)制和發(fā)布訂閱機(jī)制是很相似的:發(fā)布了一個(gè)事件后,監(jiān)聽該類型事件的所有監(jiān)聽器會(huì)觸發(fā)相應(yīng)的處理邏輯,需要的朋友可以參考下
    2024-01-01
  • Java超詳細(xì)分析講解final關(guān)鍵字的用法

    Java超詳細(xì)分析講解final關(guān)鍵字的用法

    關(guān)于final關(guān)鍵字,它也是我們一個(gè)經(jīng)常用的關(guān)鍵字,可以修飾在類上、或者修飾在變量、方法上,以此看來定義它的一些不可變性!像我們經(jīng)常使用的String類中,它便是final來修飾的類,并且它的字符數(shù)組也是被final所修飾的。但是一些final的一些細(xì)節(jié)你真的了解過嗎
    2022-06-06
  • java中final與finally的使用介紹

    java中final與finally的使用介紹

    本篇文章介紹了,在java中final與finally的使用。需要的朋友參考下
    2013-04-04
  • springboot訪問請求404的原因及解決辦法

    springboot訪問請求404的原因及解決辦法

    在使用Spring Boot開發(fā)應(yīng)用程序時(shí),有時(shí)可能會(huì)遇到訪問請求出現(xiàn)404錯(cuò)誤的情況,即請求的資源未找到,這篇文章主要給大家介紹了關(guān)于springboot訪問請求404的原因及解決辦法,需要的朋友可以參考下
    2023-09-09

最新評(píng)論