在實際開發中,對於一些通用業務和公共組件,咱們可能想將其作成一個Spring Boot Starter便於全部系統使用,這就須要咱們定義本身的Spring Boot Starter。
本文不會編寫一個真正的Spring Boot Starter,而是選擇借用mybatis-spring-boot-starter來描述starter的製做方式。之因此選擇mybatis的spring-boot-starter進行講解,一是考慮到mybatis比較重要,你們都很熟悉。二是mybatis的spring-boot-starter不是spring官方提供的,是由mybatis本身實現的。
先來思考一下,一個Spring Boot Starter都須要具有哪些能力:java
mybatis.mapperLocations=classpath:mapping/*.xml
便可。下面咱們帶着這幾個問題,來看mybatis-spring-boot-starter是如何實現的。git
這一點比較好理解,就是利用maven的間接依賴特性,在Starter的maven pom.xml中聲明全部須要的dependency,這樣在項目工程導入這個Starter時,相關的依賴就都被一塊兒導入了。下面是mybatis-spring-boot-starter的pom.xml,能夠看到與集成mybatis相關的dependency都已經聲明瞭。github
<project ...> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot</artifactId> <version>2.0.1</version> </parent> <artifactId>mybatis-spring-boot-starter</artifactId> <name>mybatis-spring-boot-starter</name> <properties> <module.name>org.mybatis.spring.boot.starter</module.name> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> </dependencies> </project>
mybatis-spring-boot-autoconfigure模塊中的MybatisProperties類支持向外暴露相關的properties,它是經過@ConfigurationProperties實現的,並指定全部properties都以」mybatis「爲前綴。關於@ConfigurationProperties的具體用法可參考《Spring Boot外部化配置》
下面是MybatisProperties類的部分源碼:spring
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX) public class MybatisProperties { public static final String MYBATIS_PREFIX = "mybatis"; private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); /** * Location of MyBatis xml config file. */ private String configLocation; /** * Locations of MyBatis mapper files. */ private String[] mapperLocations; /** * Packages to search type aliases. (Package delimiters are ",; \t\n") */ private String typeAliasesPackage; /** * The super class for filtering type alias. If this not specifies, the MyBatis deal as type alias all classes that * searched from typeAliasesPackage. */ private Class<?> typeAliasesSuperType;
能夠看到,咱們使用mybatis的全部屬性均可以經過properties的形式在application.properties中配置。sql
自動裝配的原理已經在《Spring Boot自動裝配詳解》一問中介紹過。mybatis-spring-boot-autoconfigure模塊提供了兩個自動裝配類—— MybatisAutoConfiguration和MybatisLanguageDriverAutoConfiguration,其中主要的配置功能是在MybatisAutoConfiguration中實現的,下面是MybatisAutoConfiguration類的部分源碼:segmentfault
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class }) @ConditionalOnSingleCandidate(DataSource.class) @EnableConfigurationProperties(MybatisProperties.class) @AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class }) public class MybatisAutoConfiguration implements InitializingBean { ... @Bean @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setVfs(SpringBootVFS.class); if (StringUtils.hasText(this.properties.getConfigLocation())) { factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation())); } applyConfiguration(factory); if (this.properties.getConfigurationProperties() != null) { factory.setConfigurationProperties(this.properties.getConfigurationProperties()); } if (!ObjectUtils.isEmpty(this.interceptors)) { factory.setPlugins(this.interceptors); } ... } ...
能夠看到,MybatisAutoConfiguration也是利用條件註解的方式構建各個須要的Bean,例如上面代碼片斷中建立的sqlSessionFactory Bean。
其中@AutoConfigureAfter
註解在以前沒有說明過,它是一個hint註解,在這裏的做用是隻有當DataSourceAutoConfiguration和MybatisLanguageDriverAutoConfiguration這兩個自動裝配類執行完成後,再執行MybatisAutoConfiguration的自動裝配功能。mybatis
上面只是完成了AutoConfiguration類的編寫,那麼如何讓其在Spring Boot應用啓動時執行呢?
還記得EnableAutoConfiguration
這個註解嗎?它是利用SpringFactoriesLoader機制加載全部的AutoConfiguration類的。因此咱們還須要將寫好的AutoConfiguration類放置到META-INF/spring.factories中。
在mybatis-spring-boot-autoconfigure模塊的META-INF/spring.factories文件中有下面配置代碼:app
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\ org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
這樣,在Spring Boot應用啓動時,就能夠加載並執行MybatisLanguageDriverAutoConfiguration和MybatisAutoConfiguration這兩個自動裝配類了。maven
建立自定義的Spring Boot Starter並非什麼難事。經過對mybatis-spring-boot-starter的實現方式進行分析,能夠總結出下面建立自定義starter的步驟:spring-boot