springboot的好处?
使用springboot开发时,带给我们最大的好处就是不用再自己去配置springMVC那么多的XML,只要按照springboot定义的规范,我们就可以以最小的配置实现我们的功能;
例如:
如果我们想在项目中使用rabbitmq,只要实现下面3个步骤就可以:
1.引入mq的starter组件
2.在application.properties 文件中配置mq相关的信息
3.启动本地rabbitmq-server
可以看出在springboot中使用mq就是这么简单!
那么你有没有想过背后的原理是什么?即:springboot的自动配置原理
首先我们在使用springboot时,都需要在启动类上面使用@SpringBootApplication注解。
所以springboot的自动配置一定会和这个注解有一些关系!
@SpringBootApplication
首先可以看出@SpringBootApplication是一个复合注解,其中包括:
1.@SpringBootConfiguration
2.@EnableAutoConfiguration
下面看一下这两个注解的作用:
@SpringBootConfiguration
@SpringBootConfiguration注解,又引入了@Configuratio注解,其实@SpringBootConfiguration注解就是一个配置类
@EnableAutoConfiguration
可以看出@EnableAutoConfiguratio也是一个复合注解,其中包括:
1.@AutoConfigurationPackage 注:主要实现本地项目bean的注入
2.@Import({AutoConfigurationImportSelector.class}) 注:实现自动配置的关键
下面看一下是如何自动配置的:
AutoConfigurationImportSelector.class:
下面我大体说一下上面4个步骤的主要用途(PS:可以自己debug跟一下):
1.主要读取spring-boot-autoconfigute包META-INFO/factories内容
读取的内容为# Auto Configur下面的内容,共109条(springboot默认加载的组件)
2. 获取哪儿些组件不需要自动配置
通过在启动类上面添加注解:@Exclulde和@ExcludeName实现
3.删除掉不需要自动配置的组件(从109条中删除)
4.按需加载组件到容器中;注:该步骤最为重要
因为如果每次启动都加载109个组件,会影响启动效率,还有可能造成资源浪费,可能我根本不需要这些组件;
最好就是按需加载,我需要哪儿些组件就自动装配哪儿些;
那么springboot是怎么做的呢?
通过源码跟踪:第4步骤,实现过滤的主要实现是通过@ConditionalOnClass注解来实现的;
@ConditionalOnClass:当类路径下有指定类的条件下,才生效,即:加载该配置
下面还是为mq为例:
1.首先我们知道默认加载109个组件(其中包含我们要加载的mq)
2.找到org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration 类
3.查看RabbitAutoConfiguration 类信息
4.@ConditionalOnClass({RabbitTemplate.class, Channel.class}) 意思是只有在类类路径下有RabbitTemplate.class时该配置才会生效,那么RabbitTemplate.class到底存在不存在呢?
5.还记得我们pom.xml中引入mq的starter嘛?
看到这里是不是就全明白了?这个就是springboot 自动装配的实现原理!
springboot已经把各种关于数据库,消息队列等等一些常用到的技术点,都封装成starter组件的形式进行集成,来达到自动装配的目的。
autoconfig配置类中一些注解的作用:
@ConditionalOnBean:当容器里有指定的bean的条件下
@ConditionalOnMissingBean:当容器里不存在指定bean的条件下
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnMissingClass:当类路径下不存在指定类的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true
参看文章: