Spring Boot之自定义Starter

229 阅读3分钟

Spring Boot之自定义Starter

一、开发自定义Starter

添加依赖

创建Maven项目,添加依赖

<groupId>cn.ybzy.springboot</groupId>
    <artifactId>mystarter-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starters</artifactId>
        <version>2.3.8.RELEASE</version>
    </parent>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>

定义服务类

定义服务接口

public interface IMyStarterService {

    String myStarterTest(String value)
}

定义服务接口的实现

public class MyStarterServiceImpl implements IMyStarterService {

    @Override
    public String myStarterTest(String value) {
        return value + " My Starter";
    }
}

自动配置条件依赖

完成自动配置是有依赖条件的,需配和使用SpringBoot特有的注解,常见的条件依赖注解有:

注解功能说明
@ConditionalOnBean仅在当前上下文中存在某个bean时,才会实例化这个Bean
@ConditionalOnClass某个class位于类路径上,才会实例化这个Bean
@ConditionalOnExpression当表达式为true的时候,才会实例化这个Bean
@ConditionalOnMissingBean仅在当前上下文中不存在某个bean时,才会实例化这个Bean
@ConditionalOnMissingClass某个class在类路径上不存在的时候,才会实例化这个Bean
@ConditionalOnNotWebApplication不是web应用时才会实例化这个Bean
@AutoConfigureAfter在某个bean完成自动配置后实例化这个bean
@AutoConfigureBefore在某个bean完成自动配置前实例化这个bean
@ConditionalOnProperty通过配置文件中的属性值来控制@Configuration是否生效

定义spring.factories

在resources目录下创建META-INF目录,在META-INF目录创建spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.ybzy.springboot.configure.MyStarterAutoConfigure 

定义自动配置类

@Configuration
// 类路径下发现XXX.class就自动配置
@ConditionalOnClass(value = { IMyStarterService.class, MyStarterServiceImpl.class})
public class MyStarterAutoConfigure {

    @Bean // 实例化IMyStarterService并载入Spring IoC容器
    @ConditionalOnMissingBean // 当spring上下文中不存在bean时实现自动配置
    IMyStarterService myStarterService() {
        return new MyStarterServiceImpl();
    }
}

二、使用自定义Starter

安装Starter到本地仓库

mvn clean install -Dmaven.test.skip=true

导入自定义starter

在某项目添加自定义Starter

	  <dependency>
            <groupId>cn.ybzy.springboot</groupId>
            <artifactId>mystarter-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class MyStarterServiceTest {

	 //IMyStarterService在自定义的starter中已经完成了自动配置,所以此处可以直接注入
    @Autowired
    private IMyStarterService myStarterService ;
    
    @Test
    public void testSplitVersion() {
        System.out.println(myStarterService.myStarterTest("Hello "));
    }
}

三、自定义多数据源Starter

创建DataSourceProperties配置类

@Component
@ConfigurationProperties(prefix = "spring.jdbc.datasource")
@Data
public class DataSourceProperties2 {

    private String driverClassName;
    private String url;
    private String username;
    private String password;    
}

创建DataSourceAutoConfiguration配置类

@SpringBootConfiguration
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {

    @Autowired
    private DataSourceProperties dataSourceProperties ;

    @Bean
    @ConditionalOnProperty(value = "spring.jdbc.datasource.type",havingValue = "druid")
    public DataSource createDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        dataSource.setUrl(dataSourceProperties.getUrl());
        dataSource.setUsername(dataSourceProperties.getUsername());
        dataSource.setPassword(dataSourceProperties.getPassword());
        return dataSource;
    }

    @Bean
    @ConditionalOnProperty(value = "spring.jdbc.datasource.type",havingValue = "c3p0")
    public DataSource createC3P0DataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(dataSourceProperties.getDriverClassName());
        dataSource.setJdbcUrl(dataSourceProperties.getUrl());
        dataSource.setUser(dataSourceProperties.getUsername());
        dataSource.setPassword(dataSourceProperties.getPassword());
        return dataSource;
    }
}

定义spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.ybzy.springboot.autoconfig.DataSourceAutoConfiguration

安装Starter到本地仓库

mvn clean install -Dmaven.test.skip=true

使用自定义多数据源Starter

	  <dependency>
            <groupId>cn.ybzy.springboot</groupId>
            <artifactId>jdbc-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

配置数据源信息

spring:
  jdbc:
    datasource:
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql:///demo
      username: root
      password: 123456
      type: druid
     #type: c3p0

测试

@RestController
public class HelloController {
    @Autowired
    DataSource dataSource;

    @RequestMapping("/hello")
    public String hello(String name){
        System.out.println("dataSource.getClass() = " + dataSource.getClass());
        return "Hello: "+ name ;
    }
}