美文网首页
自定义 spring-boot自动配置类

自定义 spring-boot自动配置类

作者: 卫渐行 | 来源:发表于2020-03-21 21:25 被阅读0次

文章目标

1:简介自动配置类的作用
2:如何实现Spring-data-jpa的自动化配置类
3:简单介绍@conditional核心注解,并且如何运用这些注解

概论

简而言之,Spring Boot自动配置是一种基于类路径上的依赖关系,对Spring应用实现自动配置的方法。 通过重写实现自动配置类中包含的某些bean的需求,这可以使开发更快,更容易。

接下来,我们通过例子,来实现并且了解一下如何实现Spring boot自动化配置类

maven 的依赖

实现Spring-data-jpa的自动化配置类,首先需要加入如下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>

选择自己对应的Spring-boot 版本号以及mysql 驱动类的版本

自定义auto-configuration

创建自定义配置类,我们需要创建一个@COnfiguration的注解类,并且进行注册

自定义mysql的数据源配置

@Configuration
public` `class` `MySQLAutoconfiguration {
  ``//...
}

下一步强制性的就是将自动配置类配置到resources/META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.john.autoconfiguration.MySQLAutoconfiguration

如果想让自定义的配置类有更高的执行权下,需要在配置类上加上@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)的注解

自动配置类主要是通过在类和bean加入@Conditional的注解,来实现类的自动化配置;只有在应用程序中未定义自动配置的Bean时,自动配置才有效。如果定义了bean,则默认的bean将被覆盖。

conditions 类/以及Spring bean

@CondtionalOnClass注解,表明当某个类出现在扫描的包上,该配置生效
@ConditionalOnMissingClass ;表明当某个类未出现在扫描的包上,该配置就生效
@ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件
以上注解都是元注解@Conditional演变而来的,根据不用的条件对应创建以上的具体条件注解

condition 类

当我们想自定义一个mysql的配置类,当出现datasource类是就就行如下配置,可以设置如下

@Configuration
@ConditionalOnClass``(DataSource.``class``)
public` `class` `MySQLAutoconfiguration {
  ``//...
}

condition bean

为了增强配置类的,通过如果有datasource的bean,则创建工厂类;如果没有一个类叫做entityManagerFactory 则创建改bean

@Bean
    @ConditionalOnBean(name = "dataSource")
    @ConditionalOnMissingBean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em
                = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("com.john.autoconfiguration");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        if (additionalProperties() != null) {
            em.setJpaProperties(additionalProperties());
        }
        return em;
    }

如果没有事务管理的bean,则配置事务管理

@Bean
@ConditionalOnMissingBean(type = "JpaTransactionManager")
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory);
    return transactionManager;
}

就如上面介绍的 @ConditionalOnProperty 的注解,代表着某个值已经配置化了,就bean生效;首先通过读取特定配置文件,使得JDBC生效;

首先我们引入自定义配置文件中外部变量,

@PropertySource``(``"classpath:mysql.properties"``)
public` `class` `MySQLAutoconfiguration {
  ``//...
}

在配置文件汇总设置一个mysqlconfig的属性,如果值为local的话,本地的datasource就生效,

@Bean
@ConditionalOnProperty(
        name = "mysqlconfig",
        havingValue = "local")
@ConditionalOnMissingBean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3307/test?createDatabaseIfNotExist=true");
    dataSource.setUsername("mysqluser");
    dataSource.setPassword("mysqlpass");

    return dataSource;
}

也可以设置一个自定义的datasource;默认的配置如下

@Bean(name = "dataSource")
@ConditionalOnProperty(
        name = "usemysql",
        havingValue = "custom")
@ConditionalOnMissingBean
public DataSource dataSource2() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl(env.getProperty("mysql.url"));
    dataSource.setUsername(env.getProperty("mysql.user") != null
            ? env.getProperty("mysql.user") : "");
    dataSource.setPassword(env.getProperty("mysql.pass") != null
            ? env.getProperty("mysql.pass") : "");

    return dataSource;
}

资源条件

通过@ConditionalOnResource 注解某个具体资源配置i后,某个配置就生效的,让我们定义如下的方法,本地自定义hibernate的自定义condition,重写 *getMatchOutcome* 的方法

参考文章:

Create a Custom Auto-Configuration with Spring Boot

相关文章

网友评论

      本文标题:自定义 spring-boot自动配置类

      本文链接:https://www.haomeiwen.com/subject/msxpyhtx.html