小代學Spring Boot之自定義Starter

程式碼無止境發表於2019-07-23

想要獲取更多文章可以訪問我的部落格 - 程式碼無止境

使用Spring Boot框架一段時間之後的小代同學,發現在Spring Boot專案中經常會引入各種各樣的Starter,例如Web專案的spring-boot-starter-web以及整合MyBatis時的mybatis-spring-boot-starter。那麼這個Starter到底是些什麼呢?

什麼是Starter

經過一番研究,小代同學瞭解到Starter主要是Spring Boot用來簡化專案依賴的一種形式,比如spring-boot-starter-web中包含了一個Web專案通常所需要的依賴,這樣我們就只需要依賴一個Starter即可,無需一個一個的新增所有的Web專案所需的Jar包,而且我們還可以通過Starter來做一些自動配置。

作為一個喜歡研究的程式設計師,小代同學就想能不能將之前連線MyBatis的過程封裝成一個Starter,這樣以後其他專案整合MyBatis就會簡單許多了。如果你想了解Spring Boot整合MyBatis相關的內容,可以檢視之前的文章《小代學Spring Boot之整合MyBatis》。在開始實現之前,小代同學查詢了一下Starter的命名規範。

Starter的命名規範

1.Spring Boot自己提供的一些Starter的命名一般以spring-boot-starter-xxx命名,例如spring-boot-starter-web
2.我們自己定義的Starter通常情況下以xxx-spring-boot-starter的形式命名。

自定義Starter

知道如何命名一個自定義Starter之後,小代同學根據命名的建議新建了一個mybatis-config-spring-boot-starter的專案。並且將之前整合MyBatis時候新增的依賴全部新增進來了。
新增完依賴之後,我們還需要一個配置類用來在專案啟動時自動配置連線池以及掃描Mapper檔案。所以小代同學新建了一個MyBatisAutoConfiguration類來做這些東西。

@Configuration
@EnableConfigurationProperties({MyBatisProperties.class, DruidDataSourceProperties.class})
public class MyBatisAutoConfiguration {

    @Autowired
    private MyBatisProperties myBatisProperties;

    @Autowired
    private DruidDataSourceProperties druidDataSourceProperties;

    ...此處省略若干程式碼。

    @Bean(name = "sqlSessionFactory")
    @ConditionalOnMissingBean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("druidDataSource") DruidDataSource druidDataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(druidDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(myBatisProperties.getMapperXmlLocation()));
        return sessionFactory.getObject();
    }

}

由於與之前整合MyBatis的配置大體一致,所以上面貼上的程式碼有很多被省略的部分,您可以在原始碼中找到。其實也就是將之前整合MyBatis的配置Copy過來然後稍作修改,主要有以下幾點修改:

  1. 定義了MyBatisProperties類,這個類主要是從配置檔案中讀取Mapper.xml的地址。配置會話工廠sqlSessionFactory的時候設定的MapperLocation的路徑就是從這裡獲取的。
  2. 去除了之前配置類上的@MapperScan註解,去掉的原因是我沒有找到在註解中如何獲取配置檔案中的值,所以將它挪到了使用這個Starter的專案的啟動類上。

編寫完上面的自動配置類後,我們需要做的是讓Spring Boot知道在啟動的時候需要執行這個配置類中的程式碼,實現的方式是在resources資料夾下新建META-INF/spring.factories檔案,裡面的內容如下所示。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.itweknow.mybatisconfigspringbootstarter.config.MyBatisAutoConfiguration

好了,到這一步我們整合MyBatis的Starter就已經完工了,接下來我們就來準備一個專案來測試一下吧。

Starter的使用

小代同學為了測試自己定義的Starter,特地新建了一個專案starter-test。然後小代同學充滿信心地將上面定義的Starter新增到了測試專案中。

<dependency>
    <groupId>cn.itweknow</groupId>
    <artifactId>mybatis-config-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

新增了依賴之後,小代同學編寫了一些簡單的測試程式碼,具體的測試程式碼在這裡就不貼出來了,大家可以在原始碼中找到。但是第一次測試不幸的失敗了,失敗的原因是Mapper類都沒有被初始化,原來是忘了在啟動類上新增@MapperScan註解,加上之後就可以完成測試了。

結束語

本文主要以Spring Boot整合MyBatis為例帶大家一起了解了一下如何實現一個Spring Boot專案的Starter。但是在實現過程中有一點點遺憾,就是沒有找到在@MapperScan裡使用配置檔案中配置的包路徑的方法,如果您知道的話歡迎提交Pull Request。本文的完整實現您可以在Github上找到,如果您喜歡這篇文章的話可以給個Star哦。

PS:學習不止,碼不停蹄!如果您喜歡我的文章,就關注我吧!

掃碼關注“程式碼無止境”

相關文章