美文网首页Java
SpringBoot初体验

SpringBoot初体验

作者: 愤怒的老照 | 来源:发表于2020-03-06 11:01 被阅读0次

    学习Springboot之前,肯定要有javaweb、Spring的基础,在没有接触Springboot的时候,并不能体会Springboot的简便,但是Springboot确实很火,就花了时间学习了一下,发现开箱即用,几乎不需要配置。既然SpringBoot的核心是Spring,为什么Spring的配置都不需要了呢?跟着百度,糊里糊涂的了解了一下,只是了解了一下思路...

    疑惑一:自动配置

    • Springboot是如何让我们不需要配置,就可以使用呢?
      最重要的还是@SpringBootApplication注解,这个注解标注为该类是一个应用的启动类,点开之后,发现是一个复合注解
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication {}
    
    1. @ComponentScan:这个注解是组件扫描这个是我们最熟悉的注解,即使没有使用过注解也经常在spring的配置文件中使用过<context:component-scan base-package="com.xxx.xxx"/>, 组件扫描就是扫描指定的包下的类,并加载符合条件的组件。
    2. @SpringBootConfiguration:其实就是一个@Configuration,表明这是一个配置类
    3. @EnableAutoConfiguration:这是自动配置最重要的一个注解了,开启自动配置功能,以前需要自动配置的东西,Spring Boot帮我们自动配置
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {
        String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
        Class<?>[] exclude() default {};
    
        String[] excludeName() default {};
    }
    

    @AutoConfigurationPackage:将主配置类所在的包下的所有组件,添加到Spring容器中

    @Import:给容器导入AutoConfigurationImportSelector组件,其中有一个selectImports方法 1.png 跟着代码走进来,发现资源是从类路径下的META-INF/spring.factories获取EnableAutoConfiguration指定的值,点开自动配置依赖的spring.factories: 2.png

    ,这也就是为什么不需要我们配置的原因了,Springboot帮我们配置好了

    疑惑二:自动配置条件

    参考DataSourceConfiguration,
    数据源有三个配置,不可能将三个都加载到容器中,这时候@Conditional条件判断就起作用了:

    @Configuration(proxyBeanMethods = false)
    // tomcat自带的datasource连接池,由于默认情况下spring-boot未引入org.apache.tomcat.jdbc.pool.DataSource对应的依赖包,
           // 根据@ConditionalOnClass注解的作用,这个配置不会生效
        @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
        @ConditionalOnMissingBean(DataSource.class)
        @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
                matchIfMissing = true)
        static class Tomcat {}
            // 这是SpringBoot默认的数据源
        /**
         * Hikari DataSource configuration.
         */
        @Configuration(proxyBeanMethods = false)
            // 存在这个class,继续执行
        @ConditionalOnClass(HikariDataSource.class)
        // 如果不存在数据源bean,才继续执行,如果我们添加Druid数据源,此处就不在继续执行
        @ConditionalOnMissingBean(DataSource.class)
            // 配置文件中存在spring.datasource.type,且为com.zaxxer.hikari.HikariDataSource,或者不存在这个属性的时候,继续执行
        @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
                matchIfMissing = true)
        static class Hikari {}
    
        /**
         * DBCP DataSource configuration.
         */
        @Configuration(proxyBeanMethods = false)
        @ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)
            // 上一步已经加载了DataSource,这一步不再执行
        @ConditionalOnMissingBean(DataSource.class)
        @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource",
                matchIfMissing = true)
        static class Dbcp2 {}
    
        /**
         * Generic DataSource configuration.
         */
        // 如果配置了Druid或其他数据源,会创建默认的Bean,否则跳过
        @Configuration(proxyBeanMethods = false)
        @ConditionalOnMissingBean(DataSource.class)
        @ConditionalOnProperty(name = "spring.datasource.type")
        static class Generic {
    
            @Bean
            DataSource dataSource(DataSourceProperties properties) {
                return properties.initializeDataSourceBuilder().build();
            }
    
        }
    
    
    

    从上面的代码可以知道spring-boot默认实现了hikari连接池,我们如果想更换为Druid连接池,只需要引入相应的连接池,并spring.datasource.type配置为Druid的类,所以Springboot会根据各种条件,来确保只有一项可以生效。

    参考自:
    https://blog.csdn.net/song_java/article/details/86509971
    https://github.com/lxy-go/SpringBoot

    相关文章

      网友评论

        本文标题:SpringBoot初体验

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