Spring开发一个简单的starter——c3p0自动配置

2021-01-28 10:16

阅读:488

标签:sso   size   har   yml   控制   utf-8   ram   character   创建项目   

上篇文章写了spring boot自动配置原理,现在尝试自己开发一个starter,供给spring boot完成自动配置。

在这里我们就用c3p0连接池为例,c3p0是一个比较老的连接池,在远程仓库也没有对应的starter。所以在这里的目的就是开发一个简单的c3p0的starter,达到的效果就是像使用过的driud连接池一样,在yml文件指定一些配置信息,数据源就可以自动装配好了。

在创建项目之前,先说明一下spring官方对自定义starter命名的规范和约定,spring boot官方的starter的命名规范是“spring-boot-starter-模块名”,如tomcat:spring-boot-starter-tomcat。那么自定义的starter命名规范是“模块名-spring-boot-starter”,如mybatis:mybatis-spring-boot-starter。自定义跟官方的区别就是模块名放在了后面,这样做的目的就是有区别于官方的starter。

打开idea新建一个普通的maven项目,命名为c3p0-spring-boot-starter。

1、pom.xml添加依赖:

properties>
    java.version>1.8java.version>
    spring.boot.version>2.2.4.RELEASEspring.boot.version>
properties>

dependencies>
    
    dependency>
        groupId>c3p0groupId>
        artifactId>c3p0artifactId>
        version>0.9.1.2version>
    dependency>
    
    dependency>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-autoconfigureartifactId>
        version>${spring.boot.version}version>
    dependency>
    
    dependency>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-configuration-processorartifactId>
        version>${spring.boot.version}version>
    dependency>
dependencies>

2、添加自动配置类

根据spring boot的约定,创建一个org.c3p0.spring.boot.autoconfigure的package:

技术图片

在包中创建C3p0DatasourceAutoConfigure类,这个也是c3p0的核心自动配置类。在类之上,也要添加一些注解,首先添加@Configuration标识这是一个配置类,然后就是添加条件注解,如下代码:

@Configuration
/**
 * c3p0里面的数据源的类就是ComboPooledDataSource
 * 当ComboPooledDataSource存在classpath时,则初始化当前配置类
 */
@ConditionalOnClass(ComboPooledDataSource.class)
public class C3p0DatasourceAutoConfigure {
}

3、读取yml配置文件的配置信息并松散绑定

spring boot是在properties或者yml文件中进行配置的,所以自动配置就要把配置文件中的配置信息绑定到类中,在这里新建一个C3p0DatasourceProperties用于yml的松散绑定。这个类中的属性就是连接池所需要的属性,这里简单列举几条。

技术图片

/**
 * 松散绑定,prefix表明在yml的前缀
 */
@ConfigurationProperties(prefix = "spring.datasource.c3p0")
public class C3p0DatasourceProperties {

    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private Integer minPoolSize;
    private Integer maxPoolSize;
    private Integer initialPoolSize;

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getMinPoolSize() {
        return minPoolSize;
    }

    public void setMinPoolSize(Integer minPoolSize) {
        this.minPoolSize = minPoolSize;
    }

    public Integer getMaxPoolSize() {
        return maxPoolSize;
    }

    public void setMaxPoolSize(Integer maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
    }

    public Integer getInitialPoolSize() {
        return initialPoolSize;
    }

    public void setInitialPoolSize(Integer initialPoolSize) {
        this.initialPoolSize = initialPoolSize;
    }
}

写完这些后,会发现在C3p0DatasourceProperties上的@ConfigurationProperties注解中有报红,原因是当我们使用这个注解标注一个类的时候,spring默认是不会将这个类纳入ioc容器管理的,除非在类上加入@Component注解,当然还有另外一个方式,就是在配置类上加@EnableConfigurationProperties注解:

@Configuration
/**
 * 当ComboPooledDataSource存在classpath时,则初始化当前配置类
 */
@ConditionalOnClass(ComboPooledDataSource.class)
/**
 * 将带有@ConfigurationProperties注解的类纳入spring容器管理
 */
@EnableConfigurationProperties(C3p0DatasourceProperties.class)
public class C3p0DatasourceAutoConfigure {
}

4、编写核心自动配置类

接下来就是要配置数据源了:

@Configuration
/**
 * 当ComboPooledDataSource存在classpath时,则初始化当前配置类
 */
@ConditionalOnClass(ComboPooledDataSource.class)
/**
 * 将带有@ConfigurationProperties注解的类纳入spring容器管理
 */
@EnableConfigurationProperties(C3p0DatasourceProperties.class)
public class C3p0DatasourceAutoConfigure {

    @Autowired
    private C3p0DatasourceProperties properties;

    @Bean
    /**
     * 如果容器中不存在Datasource时,则创建Bean实例
     */
    @ConditionalOnMissingBean
    public DataSource dataSource(){
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            dataSource.setDriverClass(properties.getDriverClassName());
            dataSource.setJdbcUrl(properties.getUrl());
            dataSource.setUser(properties.getUsername());
            dataSource.setPassword(properties.getPassword());
            dataSource.setMinPoolSize(properties.getMinPoolSize());
            dataSource.setMaxPoolSize(properties.getMaxPoolSize());
            dataSource.setInitialPoolSize(properties.getInitialPoolSize());
            return dataSource;
        } catch (PropertyVetoException e) {
            e.printStackTrace();
            throw new RuntimeException("error. " + e);
        }
    }
}

5、创建factories文件

spring boot的自动配置原理就是扫描META-INF目录下的spring.factories文件,拿到里面的完整类名并交由spring管理,所以在自定义starter也要有这样一个目录和文件。

在resources目录下新建META-INF目录,里面新建一个spring.factories文件。

技术图片

spring.factories:

# \斜杠表示换行符
org.springframework.boot.autoconfigure.EnableAutoConfiguration=  org.c3p0.spring.boot.autoconfigure.C3p0DatasourceAutoConfigure

factories文件的key指定的是org.springframework.boot.autoconfigure.EnableAutoConfiguration,也就是开启自动配置的注解的完整类名,value就是指定自定义starter的核心自动配置类的完整类名。

这样,c3p0的starter就算开发完成。

6、打包

starter最终是要打成jar包使用的,如果要在本地使用,那么最简单的方法就是打成jar包后安装在本地仓库中。

在idea中,打开maven视图层,运行项目的install命令,这样前面的所有命令都会执行:

技术图片

当控制台报时,说明打包并安装成功,可以在其他项目中使用了。

技术图片

7、测试

新建一个spring boot项目,添加依赖:

dependencies>
    dependency>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-starter-jdbcartifactId>
    dependency>

    dependency>
        groupId>mysqlgroupId>
        artifactId>mysql-connector-javaartifactId>
        scope>runtimescope>
    dependency>

    
    dependency>
        groupId>edu.nfgroupId>
        artifactId>c3p0-spring-boot-starterartifactId>
        version>1.0version>
    dependency>

    dependency>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-starter-testartifactId>
        scope>testscope>
        exclusions>
            exclusion>
                groupId>org.junit.vintagegroupId>
                artifactId>junit-vintage-engineartifactId>
            exclusion>
        exclusions>
    dependency>
dependencies>

在yml文件中添加一些基本配置

spring:
  datasource:
    c3p0:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&useUnicode=true&characterEncoding=utf-8
      username: root
      password: root
      min-pool-size: 5
      max-pool-size: 20
      initial-pool-size: 5

测试数据源:

@SpringBootTest
class Ch08ApplicationTests {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    void testDatasource() {
        ComboPooledDataSource dataSource = (ComboPooledDataSource) jdbcTemplate.getDataSource();
        System.out.println("min-pool-size: " + dataSource.getMinPoolSize());
        List> list = jdbcTemplate.queryForList("select city_name from city_info limit 0,5");
        for (Map map : list) {
            for (String key : map.keySet()){
                System.out.println(map.get(key));
            }
        }
    }

}

 

 

 

Spring开发一个简单的starter——c3p0自动配置

标签:sso   size   har   yml   控制   utf-8   ram   character   创建项目   

原文地址:https://www.cnblogs.com/zhangcaihua/p/12838787.html


评论


亲,登录后才可以留言!