美文网首页
自定义 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