微服务核心重新认识Spring Boot,掌握核心特性及设计思想
Spring Boot" title="Spring Boot">Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
这是Spring官网对SpringBoot的定义和评价。
一、SpringBoot的前世今生
对于Spring框架而言,我们接触的比较多的是Spring framework中的SpringMVC、IOC、AOP、DI等。而这些框架在使用过程中需要进行大量的配置文件的编写,或者需要进行很多繁琐的配置才能完成项目的初始化搭建工作。Spring可以说它是万能胶,这样一点没错。下面我们来使用SpringMVC去构建一个Web项目,看看其步骤有多么的繁琐吧。
- 1、创建一个项目结构(maven/gradle)
- 2、spring的依赖,spring mvc 、servlet api的依赖
- 3、web.xml, DispatcherServlet
- 4、启动一个Spring mVC的配置,Dispatcher-servlet.xml
- 5、创建一个Controller 发布一个http请求
- 6、发布到jsp/servlet容器
1.1 SpringBoot的产生过程
2012年10月份,一个叫Mike Youngstrom(扬斯特罗姆)在Spring Jira中创建了一个功能请求,要求在Spring Framework中支持无容器Web应用程序体系结构,他谈到了在主容器引导 spring 容器
内配置 Web 容器服务。
SpringBoot刚出生的时候,引起了很多开源社区的关注,并且也有个人和企业开始尝试使用SpringBoot。 其实直到2016年,SpringBoot才真正在国内被使用起来。
1.2 到底什么是SpringBoot
SpringBoot 框架是为了能够帮助使用Spring框架的开发者快速高效的构建一个基于Spirng框架以及Spring生态体系的应用解决方案。它是对“约定优于配置”这个理念下的一个最佳实践。因此它是一个服务于框架的框架,服务的范围是简化配置文件。
什么才是约定优于配置呢?
只要依赖的spring-boot-starter-web的jar,就会自动内置一个tomcat容器(替换)
项目结构
默认提供了配置文件application.properties/yml
starter启动依赖 - 如果是一个webstarter ,默认认为你是去构建一个spring mvc的应用.
EnableAutoConfiguration 默认对于依赖的 starter 进行自动装载
二、SpringBoot与微服务
那为什么Spring Cloud会采用Spring Boot来作为基础框架呢?原因很简单
- Spring Cloud它是关注服务治理领域的解决方案,而服务治理是依托于服务架构之上,所以它仍然需要一个承载框架;
- Spring Boot 可以简单认为它是一套快速配置Spring应用的脚手架,它可以快速开发单个微服务,所以Spring Cloud的版本和Spring Boot版本的兼容性有很大关联。
三、Spring注解驱动的发展过程
3.1 Spring 1.x
在SpringFramework1.x时代,其中在1.2.0是这个时代的分水岭,当时Java5刚刚发布,业界正兴起了使用Annotation的技术风,SpringFramework自然也提供了支持,比如当时已经支持了@Transactional等注解,但是这个时候,XML配置方式还是唯一选择。
3.2 Spring 2.x
Spring Framework2.x时代,2.0版本在Annotation中添加了@Required、@Repository以及AOP相关的@Aspect等注解,同时也提升了XML配置能力,也就是可扩展的XML,比如Dubbo这样的开源框架就是基于SpringXML的扩展来完美的集成Spring,从而降低了Dubbo使用的门槛。
在2.x时代,2.5版本也是这个时代的分水岭, 它引入了一些很核心的Annotation
- @Autowired 依赖注入
- @Qualifier 依赖查找
- @Component、@Service 组件声明
- @Controller、@RequestMappring等spring mvc的注解
尽管Spring 2.x时代提供了不少的注解,但是仍然没有脱离XML配置驱动,比如context:annotation-config context:componet-scan,前者的职责是注册Annotation处理器,后者是负责扫描classpath下指定包路径下被Spring模式注解标注的类,将他们注册成为Spring Bean
- @Required
- @Repository(Dao)
- @Aspect
spring 2.5
- @Component (组件)
- @Service service(服务接口)
- @Controller(控制器)
- @RequetsMapping(请求映射器)
3.3 Spring 3.x
Spring Framework3.0是一个里程碑式的时代,他的功能特性开始出现了非常大的扩展,比如全面拥抱Java5、以及Spring Annotation。更重要的是,它提供了配置类注解@Configuration,它出现的首要任务就是取代XML配置方式。
实现无配置化的方式实现Bean的装配。
- @Configuraion (去xml化)
把Bean的对象如何以便捷的方式加载到Spring IOC容器中
- ComponentScan(扫描@Service、@Controller、@Repository)
- Import(把多个容器配置合并在一个配置中)
Enable模块驱动
在Spring 3.1中,提供了很多以@Enable开头的注解,比如:
- @EnableWebMvc(引入MVC框架在Spring应用中需要用到的所有的Bean)
- @EnableScheduling(开启任务计划)
- @EnableAutoConfiguration
- @Bean(来声明一个bean)
3.4 Spring 4.x
@Conditional(选择性的对加载的bean进行条件过滤)
3.5 Spring 5.x
四、SpringBoot的特性
首先分析特性的时候,我们不妨从SrpingBootApplication的注解入手,看看它做了什么,首先打开注解的源码:
@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 {
......
}
SpringBootApplication 本质上是由 3 个注解组成,分别是:
- @Configuration;
- @EnableAutoConfiguration;
- @ComponentScan。
可以直接用这三个注解也可以启动SpringBoot应用,只是每次配置三个注解比较繁琐,所以直接用一个复合注解更方便些。后面会逐一详尽分析这些注解的,这里先简单介绍一下。
4.1 EnableAutoConfiguration自动装配
打开EnableAutoConfigration注解的源码,不难发现会带有一个@Import的注解。其实所有以Enable开头的注解都会有一个@Import注解。下面来看下源码吧。
4.1.1 @Import注解
- @EnableAutoConfiguration
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
- @EnableScheduling
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}
- @EnableWebMvc
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
类似于<import resource/>
形式的注解,就是把多个容器配置合并在一个配置中。可以配置三种不同的class:
- 普通的bean或者带有@Configuration注解的bean;
- 实现ImportSelector接口进行动态注入:
- 实现ImportBeanDefinitionRegistror接口进行动态注入。
4.1.2 EnableAutoConfiguration分析
EnableAutoConfiguration的主要作用就是把SpringBoot中所有符合条件的@Configuration配置都加载到创建并使用的IoC容器中。
在注解源码中我们看到@Import注解中配置了EnableAutoConfigurationImportSelector这个类。
EnableAutoConfigurationImportSelector又是什么呢?
从名字上看一定是实现了ImportSelector接口,所以是基于动态bean的加载功能。来看下selectImports方法的源码:
public String[] selectImports(AnnotationMetadata metadata) {try {
AnnotationAttributes attributes = this.getAttributes(metadata);
List<String> configurations = this.getCandidateConfigurations(metadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(metadata, attributes);
configurations.removeAll(exclusions);
configurations = this.sort(configurations);
this.recordWithConditionEvaluationReport(configurations, exclusions);
return (String[])configurations.toArray(new String[configurations.size()]);
} catch (IOException var5) {
throw new IllegalStateException(var5);
}
}
此处返回的String数组,是所有类的全类名,它们都会被纳入到Spring的IoC容器中。
其实 EnableAutoConfiguration会帮助SpringBoot应用把所有符合@Configuration 配置都加载到当前SpringBoot创建的IoC容器,而这里面借助了Spring框架提供的一个工具类 SpringFactoriesLoader的支持。以及用到了Spring提供的条件注解 @Conditional,选择性的针对需要加载的 bean 进行条件过滤。
4.1.3 SpringFactoriesLoader
SpringFactoriesLoader其实和java中的SPI机制是一样的。但是不会像SPI一样一次性加载所有的类,而是根据key进行加载。其key是配置在META-INF/spring.factories配置文件中,根据key来加载对于的bean到Ioc容器中。
public abstract class SpringFactoriesLoader {private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public SpringFactoriesLoader() {
}
}
SPI机制
Service provider interface
满足以下条件
需要在classpath目录下创建一个 META-INF/services;
在该目录下创建一个扩展点的全路径名:
1、文件中填写这个扩展点的实现
2、文件编码格式UTF-8
3、ServiceLoader去进行加载
4.1.4 条件过滤Conditional的分析
通过条件过滤减少带有@Configuration注解类的数量,从而减少SpringBoot的启动时间。
@Conditional中的其它注解
- @ConditionalOnBean(在存在某个bean的时候);
- @ConditionalOnMissingBean(不存在某个bean的时候);
- @ConditionalOnClass(当classpath可以找到某个类型的类时);
- @ConditionalOnMissingClass(当classpath不能找到某个类型的类时);
- @ConditionalOnResource(当前classpath是否存在某个资源文件);
- @ConditionalOnProperty(当前jvm是否包含某个系统属性的某个值);
- @ConditionalOnWebApplication(当前spring context是否是web应用程序)。
4.2 Starter
Starter相当于模块,能将模块所需要的依赖整合起来并对模块内的bean根据环境来进行自动配置。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,SpringBoot 就能自动扫描并加载相应的模块。
- 官方包 spring-boot-starter-xxx;
- 第三方包 xxx-spring-boot-starter
4.3 Actuator
SpringBoot提供了spring-boot-start-actuator支持对SpringBoot应用的监控。
<dependency><groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
4.3.1 endpoint
通过访问地址:http://localhost:8080/actuator
可以看到非常多的 Endpoint。 有一些 Endpoint 是不能访问的,涉及到安全问题。
开启所有的endpoint:(management.endpoints.web.exposure.include=* *)
- health(健康检查):management.endpoint.health.show-details= always
- Loggers(日志配置信息,针对每个package 对应的日志级别)
- beans(IoC 容器中所有的 bean)
- Dump(获取活动线程的快照)
- Mappings(全部的 uri 路径,以及和控制器的映射关系)
- conditions(当前所有的条件注解)
- shutdown(关闭应用):management.endpoint .shutdown.enabled= true,注意不要开启,比较危险
- Env(获取全部的环境信息)
4.3.2 Health的原理分析
应用健康状态的检查应该是监控系统中最基本的需求,所以我们基于 health 来分析一下它是如何实现的。
org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration类自动装配载入的,打开对应包下的spring.foctories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.CacheStatisticsAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.MetricsDropwizardAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.MetricsChannelAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.MetricExportAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.PublicMetricsAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.TraceRepositoryAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.TraceWebFilterAutoConfiguration
org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration=
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcManagementContextConfiguration,
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcHypermediaManagementContextConfiguration
Actuator 中提供了非常多的扩展点,默认情况下提供了一些常见的服务的监控检查的支持。
- DataSourceHealthIndicator
- DiskSpaceHealthIndicator
- RedisHealthIndicator
以上是 微服务核心重新认识Spring Boot,掌握核心特性及设计思想 的全部内容, 来源链接: utcz.com/a/29832.html