在实际开发中,对于一些通用业务和公共组件,咱们可能想将其作成一个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