SpringBootjava
SpringBoot是一个服务于Spring框架的框架,用来简化对于bean的获取, 快速构建一个web服务, 它的基础依然是Spring。web
在SpringBoot还未出来之前使用的最多的架构体系多是SpringMVC + Mybatis or Spring + Struts2 +Hibernate ,甚至是最先期的JSP + Servlet. 以上框架搭建起来过于繁琐,并且须要进行大量的配置,每次搭建一个web项目可能会遇到各类各样的问题,因此通常公司都会生成相应的脚手架,以便于可以提高开发效率。spring
随着互联网的发展,最开始的单体架构可能难以支撑大流量的场景, 那么架构演进的一个必然的结果是须要对于系统架构拆分,由最开始的单体架构拆分红N个业务系统,那么服务与服务之间的调用就须要提供相应的通讯方式与协议等,例如HTTP 或者RPC(dubbo的底层通讯方式是经过Netty实现,即暴露服务的端口供远程调用)的方式进行调用。api
1.什么是SpringBoottomcat
1.1. Spring基础,IOC 控制反转springboot
包含如下两部分:架构
1.2. SpringBoot实现快速开发的基础来源于 约定优于配置框架
什么是约定优于配置:例如A和B两我的刚认识,为了升华一下双方的友谊,因而约定某天某一时刻在某地喝茶, 那么第二次可能只须要说老地方见就知道该去哪里,那么到了后来可能只须要一个眼神交流便可。maven
1.2.1 约定优于配置的体现ide
maven的目录结构(默认以jar的形式打包,默认会有resources目录)
springboot-starter-xxx的方式, e.g. springboot-starter(内置了tomcat, resource/{template,static} )
1.2.2. 为何说SpringBoot里没有新技术
1.2.2.1. 自动装配
@SpringBootApplication 是由如下三个注解组成的
@SpringBootConfiguration
由
@Configuration
注解标注。 --> 本质上仍是由@Component
标注。 Spring最开始采用XML的方式 e.g. :<bean id="xxx" class ="com.xxxx.A"/>
Spring3开始支持
javaConfig
的方式(始于JDK5), Spring3之后开始支持xml
和javaConfig
的方式
@EnableAutoConfiguration
Spring3.1后引入Enable* , e.g. :
EnableScheduling
,EnableCache
EnableAsync
..
// 引入@Import({Registrar.class}) @AutoConfigurationPackage // 至关于xml: `<import resource ="***"/>`, `AutoConfigurationImportSelector`最终继承于ImportSelector @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { // .... }
ImportSelector
、ImportBeanDefinitionRegistrar
// 方式① public class CachedRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { RootBeanDefinition beanDefinition = new RootBeanDefinition(DiskPersistent.class); String beanName = StringUtils.uncapitalize(DiskPersistent.class.getName()); // beanName相當於<bean name ="beanName"></bean> beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition); } // 方式② public class ProviderSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{CachedService.class.getName(),HealthManagerService.class.getName()}; } } // 控制台打印,能够获取到以下内容,这只是个简单的演示,能够在这里作一些其余的事情(加深本身的印象) //HealthManagerService@57a4d5ee //DiskPersistent@5af5def9
AutoConfiguration
(自动注入, 简化Bean的注入)
@EnableAutoConfiguration中导入了AutoConfigurationImportSelector
经过ImportSelector不难知道其中一定会有selectImports
方法,
public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { // 这里在加载META-INF/spring-autoconfigure-metadata.properties文件 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<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); // 去重 configurations = this.removeDuplicates(configurations); //过滤注解属性exlude={} Set<String> 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); } } protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { // `SpringFactoriesLoader` (`spring SPI机制`),这里会加载全部的 `META-INF/spring.factories`文件里的数据 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
spi(service provider interface)
是什么? --> 提供扩展点供开发人员使用 e.g.java ,spring,dubbo
都提供了相应的spi
在META-INF下建立:
spring.factories
添加本身的类便可加载: e.g.:org.springframework.boot.autoconfigure.EnableAutoConfiguration= xxx.xxx.A
以下是spring自带的的:
# `AutoConfiguration` `org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.client.CommonsClientAutoConfiguration,\ org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\` // 略...
条件注册:**
由于SpringBoot会考虑到各类各样的场景,因此须要加载的资源会比较多,而有些时候大部分场景咱们压根使用不到,因此能够经过条件注解
ConditionalOnXXX
e.g.ConditionalOnClass = "com.xxx.A"
在META-INF
下添加spring-autoconfigure-metadata.properties
com.a.AConfig.ConditionalOnClass = com.xxx.A // spring中的 org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.ConditionalOnClass=org.influxdb.InfluxDB @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class})
@ComponentScan
扫描
@Component, @Service, @Controller, @Configuration
等(注解具备派生性,@Component及派生注解都将被扫描) 而后被IOC托管。
等价于 : Spring XML的方式<context-componet-scan />