资讯专栏INFORMATION COLUMN

springboot(二)——springboot自动配置解析

张率功 / 3452人阅读

摘要:前言用过的肯定很熟悉,它其中有个重要的特性,就是自动配置平时习惯的一些设置的配置作为默认配置。提倡无配置文件的理念,使用生成的应用完全不会生成任何配置代码与配置文件。

前言

用过springboot的肯定很熟悉,它其中有个重要的特性,就是自动配置(平时习惯的一些设置的配置作为默认配置)。springboot提倡无XML配置文件的理念,使用springboot生成的应用完全不会生成任何配置代码与XML配置文件。下面先看一个springboot集成mybatis的例子。
第一步: 引入pom文件

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.1
        
        
            mysql
            mysql-connector-java
            5.1.47
        

第二步: 因为我使用的xml配置文件去使用mybatis,在application.properties文件加入如下配置:

#指定mapper文件位置
mybatis.mapper-locations=classpath:mapper/*.xml

#数据源信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/zplxjj?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

第三步: 加入实体类、dao、mapper文件

第四步:启动类上面加入注解

@SpringBootApplication
@MapperScan("com.stone.zplxjj.dao")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

第五步:至此,配置完成,只需要写个单侧,springboot已经完美集成mybatis

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
    @Autowired
    UserMapper userMapper;

    @Test
    public void testMybatis() {
        System.out.println(userMapper.selectByPrimaryKey(1L));
    }
}
@EnableAutoConfiguration

通过上面的例子,我们发现集成mybatis特别简单,那些繁琐的类的注入都没有写,只需要加入数据库的一些配置即可,那这其中@EnableAutoConfiguration功不可没。@EnableAutoConfiguration 注解已经在@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 {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class[] scanBasePackageClasses() default {};
}

我们看到@EnableAutoConfiguration结构如下:

@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 {};
}

这其中起作用的一个重要注解@Import,这个Spring提供的一个注解,可以导入配置类或者Bean到当前类中,我们进入到AutoConfigurationImportSelector类中查看,方法太长,截取核心的两个方法:

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

通过项目启动后,打上注解,可以看到MybatisAutoConfiguration引入了进来

而MybatisAutoConfiguration能引入进来,其实是在mybatis-spring-boot-autoconfigure-2.0.1.jar包里面的spring.factories指定的,通过调用SpringFactoriesLoader.loadFactoryNames()来扫描加载含有META-INF/spring.factories文件的jar包,从而标识哪些自动配置的类

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
@Conditional

@Conditional 的作用,可以根据条件去加载特定的bean,原理这边不做探讨,springboot基于此实现了几个注解,比较方便的实现条件加载类
@ConditionalOnBean:Spring容器中是否存在对应的实例
@ConditionalOnMissingBean:Spring容器中是否缺少对应的实例
通过查看MybatisAutoConfiguration中的SqlSessionFactory的写法

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setVfs(SpringBootVFS.class);
        if (StringUtils.hasText(this.properties.getConfigLocation())) {
            factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
        }

        this.applyConfiguration(factory);
        if (this.properties.getConfigurationProperties() != null) {
            factory.setConfigurationProperties(this.properties.getConfigurationProperties());
        }

        if (!ObjectUtils.isEmpty(this.interceptors)) {
            factory.setPlugins(this.interceptors);
        }

        if (this.databaseIdProvider != null) {
            factory.setDatabaseIdProvider(this.databaseIdProvider);
        }

        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
            factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }

        if (this.properties.getTypeAliasesSuperType() != null) {
            factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
        }

        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
            factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }

        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
            factory.setMapperLocations(this.properties.resolveMapperLocations());
        }

        return factory.getObject();
    }
结语

通过上面分析mybatis如何集成springboot,知道了springboot入口在哪里以及如何实现的自动配置,这里只是简单的做了介绍,其中的一些源码和细节就没有分析了,我相信,入口知道了,接下来就好抠细节了。

本人也开通了微信公众号:stonezplxjj和个人博客:http://www.zplxjj.com,更多文章欢迎关注公众号:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74253.html

相关文章

  • 2019年java架构师视频

    摘要:并发专题一内存模型原理实现机制单例模式并发基础并发集合原子操作基本类型线程池互联网工程专题二简介安装工具编程介绍,入门程序仓库依赖管理简介常用操作命令 01.并发专题(一)2018-09-11(1)-Java内存模型2018-09-13(2)-synchronized原理2018-09-16(3)-volatile实现机制2018-09-18(4)-DCL-单例模式2018-09-21...

    Object 评论0 收藏0
  • SpringBoot关于JSON交互问题

    摘要:关于交互问题一交互的优势本来就是里的内容客户端可以很容易对数据解析数据格式简单易于读写带宽占用小不错的可读性可表示各类复杂性的数据。注解相当于合在一起的作用。从上面返回结果可以发现两个问题,第一许多为的字段也输出。 SpringBoot关于JSON交互问题 一、Json交互的优势 1.JSON本来就是javascript里的内容,客户端可以很容易对JSON数据解析. 2.数据格式简单...

    Dogee 评论0 收藏0
  • SpringBoot就是这么简单

    摘要:热加载代表的是我们不需要重启服务器,就能够类检测得到,重新生成类的字节码文件无论是热部署或者是热加载都是基于类加载器来完成的。验证阶段字节码文件不会对造成危害准备阶段是会赋初始值,并不是程序中的值。 一、SpringBoot入门 今天在慕课网中看见了Spring Boot这么一个教程,这个Spring Boot作为JavaWeb的学习者肯定至少会听过,但我是不知道他是什么玩意。 只是大...

    whinc 评论0 收藏0
  • springboot学习()——springmvc配置使用

    摘要:中添加拦截器配置如下拦截所有请求,也就是,只拦截开头的请求。在中并没有提供配置文件的方式来配置拦截器,因此需要使用的代码式配置,配置如下这个属性通常并不需要手动配置,高版本的会自动检测第四点讲下静态资源映射。 以下内容,如有问题,烦请指出,谢谢 上一篇讲解了springboot的helloworld部分,这一篇开始讲解如何使用springboot进行实际的应用开发,基本上寻着sprin...

    hiyayiji 评论0 收藏0
  • 基于SpringBoot的后台管理系统(启动类解析,开源的世界真好)(一)

    摘要:目前只是一个后台模块,希望自己技能增强到一定时,可以把的融合进来。目录第一站,分析了启动类。看见没,这个也是配置类,它声明了视图解析器地域解析器以及静态资源的位置,想起来没,就是前置,后置。程序启动类我们点击源码看看。 Guns基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springmvc + shiro + 分页插件PageHelper + 通用Mapper + ...

    SwordFly 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<