Springboot 目前是一个非常火的框架,它能快速开发,快速集成等优点,打破传统的一些繁琐配置以及各种配置。(在这里注意只是跟以前开发过程相比)那么springboot 具体怎么做的,现在通过自己看源码来学习一下,有不得当的地方请各位同行指出、交流。
首先我们知道在我们进行springboot 搭建的时候,在pom 文件中导入各种jar 中有一个特别亮眼的词:Starter,那么今天看一下就看下它的源码,看一下它做了什么事情。下面就以我们非常熟悉的mybatis starter 为例:
首先我们看到在starter 中有pom.xml ,大家可以点进去看一下里面有关于mybatis 的一些必要配置,这里就是将关于mybatis 相关jar 包自动导入我们的项目中。大家都知道mybatis 是第三方框架,所以初始化并不在我们spring 开头的一些自动配置类,此时 我们看到有一个mybatis-spring-boot-autoconfigure jar 包,此时我们点进去,他的类非常的少,就是初始化mybatis 运行的工作环境,具体怎么把这个配置类加载,我们可以根据主入口跟踪,有一个规则就是,springboot 在启动时会扫描主类及同级别内的类。
可以看到我们平时集成mybatis 中的类都在这里,是不是很熟悉很惊喜。这个用到了很多条件注解类,在这里不在多解释条件注解,大家可以上网查看相关资料,这里主要介绍怎么样的自动配置工作机制。
可以看到Configuration系统启动扫描该类;@ConditionalOnClass 此类初始化时必须有 SqlSessionFactory.class, SqlSessionFactoryBean.class 否则启动报错,这两个类在这里不多说;
@ConditionalOnBean(DataSource.class) 说明此类初始化以来DataSource 类,
@EnableConfigurationProperties(MybatisProperties.class) 这个就是开启属性配置,一个很关键的类,这个多说两句,经典的springboot 一个xxxAutoConfiguration 对应一个XXXProperties,这样我们就可以灵活配置相关参数,这几个重要注解解释完之后我们看下其代码,这里我就不截图了,可以看到
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
这种注解的类,将mybatis 需要的类初始化创建实例到容器中。至此mybitis 使用环境就准备就绪。在springboot 中引用差不多都是这个套路。具体细节大家可以看源码都能看的懂,不在这里过多讲解。
public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware { private BeanFactory beanFactory; private ResourceLoader resourceLoader; @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { logger.debug("Searching for mappers annotated with @Mapper"); ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); try { if (this.resourceLoader != null) { scanner.setResourceLoader(this.resourceLoader); } List<String> packages = AutoConfigurationPackages.get(this.beanFactory); if (logger.isDebugEnabled()) { for (String pkg : packages) { logger.debug("Using auto-configuration base package '{}'", pkg); } } scanner.setAnnotationClass(Mapper.class); scanner.registerFilters(); scanner.doScan(StringUtils.toStringArray(packages)); } catch (IllegalStateException ex) { logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex); } }
此段代码主要是扫描我们mapper ,此类实现ImportBeanDefinitionRegistrar ,在我们springboot 启动时会通过@import 加载这些类来进行相关初始化,并将这个@mapper 注解的类注册到容器中。
以上是不是是不是springboot 强大之处,现在应该可以感受到了,可以根据这个思路,大家看下源码,一切豁然开朗,以前通过我们要各种配置,现在一切引入xxxstarter 一切搞定。