自定义starter
在实际开发中,经常会定义一些公共组件,提供给各个项目团队使用,而在SpringBoot的项目中,一般会将这些公共组件封装为SpringBoot的 starter。
如何来自定义starter,其实就是依葫芦画瓢,照着其他的starter来就行,以下以MyBatis的starter为例
一般起步依赖有两个工程组成
我们会在starter中引入autoconfigure,别人使用只需要引入starter即可。
案例需求:我们自已仿造MyBatis的starter来自定义starter
步骤:
-
创建dmybatis-spring-boot-autoconfigure模块,提供自动配置功能,并自定义配置文件 META-INF/spring/xxx.imports
-
创建dmybatis-spring-boot-starter模块,在starter中引入自动配置模块。
首先在IDEA中创建两个Maven模块dmybatis-spring-boot-autoconfigure,以及dmybatis-spring-boot-starter
然后在dmybatis-spring-boot-autoconfigure工程里提供自动配置的功能。步骤如下
首先如果说要提供MyBatis的自动配置功能,需要先将对应依赖导入。(这一步可以借鉴MyBatis-starter)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.14</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.3</version>
</dependency>
接下来开始写自动配置类,在src包下创建config包,config包下创建MybatisAutoConfig类,
添加@AutoConfiguration注解声明为自动配置类。
再注入MyBatis需要的Bean对象:sqlSessionFactoryBean
(用来创建SQLSessionFactory,而SQLSessionFactory用来创建SQLSession,sqlSession是我们的会话对象。
接下来要连接数据库,要指定连接哪个数据库,而我们刚刚在pom文件中导入了JDBC起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<version>3.4.5</version>
</dependency>
这个起步依赖会自动地往IOC容器里面注入一个data Source数据源对象,我们只需要直接在方法上传入Data Source参数即可, 在调用方法:sqlSessionFactoryBean.setDataSource(dataSource)
连接即可,最后再返回sqlSessionFactoryBean对象)
代码如下:
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//用来创建SQLSessionFactory,而SQLSessionFactory用来创建SQLSession
sqlSessionFactoryBean.setDataSource(dataSource);//连接数据库对象
return sqlSessionFactoryBean;
}
MapperScannerConfigurer
(用来进行mapper扫描的,在配置类中需要声明要扫描哪个包以及注解)
(springboot会自动扫描启动类所在的包及其子包,因此我们也设置成扫描启动类所在的包及子包。可我们如何得知启动类所在的包名?
在springboot内部提供了相应的API:AutoConfigurationPackages
,调用get方法,get方法中需要引入Bean Factory参数,我们直接在方法上引入参数进行调用,之后返回一个集合,这个集合里面放的是包名,这个集合只需要放置启动类所在的包即可,因此集合中只有一个元素,我们只需要拿到集合第一个元素即可,在调用mapperScannerConfigurer的setBasePackage()方法扫描包即可。
扫描mapper注解,直接调用mapperScannerConfigurer的setAnnotationClass(Mapper.class)即可。)
代码如下
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(BeanFactory beanFactory){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
//扫描的包:启动类所在的包以及子包
List<String> packages = AutoConfigurationPackages.get(beanFactory);
String p = packages.get(0);
mapperScannerConfigurer.setBasePackage(p);
//扫描注解
mapperScannerConfigurer.setAnnotationClass(Mapper.class);
return mapperScannerConfigurer;
}
综合:
package com.lyc.config;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
import java.util.List;
@AutoConfiguration//声明为自动配置类
public class MybatisAutoConfig {
//sqlSessionFactoryBean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//用来创建SQLSessionFactory,而SQLSessionFactory用来创建SQLSession
sqlSessionFactoryBean.setDataSource(dataSource);//连接数据库对象
return sqlSessionFactoryBean;
}
//MapperScannerConfigurer
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(BeanFactory beanFactory){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
//扫描的包:启动类所在的包以及子包
List<String> packages = AutoConfigurationPackages.get(beanFactory);
String p = packages.get(0);
mapperScannerConfigurer.setBasePackage(p);
//扫描注解
mapperScannerConfigurer.setAnnotationClass(Mapper.class);
return mapperScannerConfigurer;
}
}
接下来需要去设置配置文件,将自动配置类的全类名放在org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件中。该配置文件需要放在resources目录下的META-INF目录下的spring目录下
这时自动配置类已经写好了,接下来写starter工程。
starter工程只是提供依赖管理的功能,所以我们只需要将需要的依赖导入pom文件即可
<dependency>
<groupId>com.lyc</groupId>
<artifactId>bmybatis-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.14</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.3</version>
</dependency>
注意事项:在导入依赖时,除了要导入我们自己写的自动配置的依赖以外,尽量将自动配置里需要的依赖也一并导入。
此时,我们的仿MyBatis-starter已经完成,最后我们可以将无关文件删除,比如autoconfigure中IDEA提供的main方法,test目录。
还有starter中的src目录都不需要,只需要一个pom文件就行了。
然后我们去进行测试,将pom文件中的MyBatis依赖替换成我们自己写的进行测试
<dependency>
<groupId>com.lyc</groupId>
<artifactId>dmybatis-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
测试:
测试成功
总结:自定义starter其实很简单:只需要提供两个工程:autoconfigure工程(提供自动配置功能)以及starter工程(依赖管理)。
希望对大家有所帮助!