SpringBoot学习小结
基于Spring,简化Spring应用开发的框架,整个Spring技术栈的大整合,J2EE开发的一站式解决方案
优点:
- 快速创建独立运行的Spring项目以及集成主流框架
- 使用嵌入式的Servlet容器,无需war包
- starters自动依赖与版本控制
- 无需XML,无代码生成,简化配置,自动配置
- 准生产环境的运行时应用监控
- 与云计算的天然集成
微服务
- 2014,重构一书作者Martin Fowler在他的个人博客中提出的
- 是一种架构风格
- 每个应用都该是一组小型服务,可以通过HTTP进行沟通
场景启动器
SpringBoot自动配置原理
- 项目启动时,会去寻找自动配置类的导入选择器,在选择器的 selectImports 方法中查找所有包下 META-INF/spring.factories文件,将文件内容解析成Properties,然后读取其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value值,然后对这些值进行过滤(重复的、被排除的),返回最后的自动配置类全路径的字符串集合。
- 每个自动配置类(AutoConfiguration)都会关联一个或多个属性类(Properties),这些Properties类都是与配置文件进行绑定的,在自动配置类中存在Properties的引用,且只包含一个参数为Properties的构造器,说明Properties引用的值来自于配置文件或者默认值,并存在向spring容器注入bean的方法,方法里面使用Properties对象的属性。
- 同时每个配置类可以包含一个或多个条件判断,只有在满足了所有条件时这个配置类才会生效。
@EnableAutoConfiguration //允许自动配置
@Import({EnableAutoConfigurationImportSelector.class}) //导入允许自动配置导入选择器,高版本以及废弃,使用ImportAuto...
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector{} //自动配置导入选择器
public class AutoConfigurationImportSelector {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
try {
//自动配置元数据
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
//从元数据读取注解属性
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//从元数据和属性获取所有配置类的字符串集合
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//处理自动配置类:去除重复的、被排除掉的等
configurations = this.removeDuplicates(configurations);
configurations = this.sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return (String[])configurations.toArray(new String[configurations.size()]);
} catch (IOException var6) {
throw new IllegalStateException(var6);
}
}
}
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//this.getSpringFactoriesLoaderFactoryClass() == EnableAutoConfiguration.class
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;
}
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
//EnableAutoConfiguration的全路径:org.springframework.boot.autoconfigure.EnableAutoConfiguration
String factoryClassName = factoryClass.getName();
try {
//读取所有META-INF/spring.factories文件,解析成URL
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
ArrayList result = new ArrayList();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
//将URL解析成Properties文件
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
//查找properties中属性名称为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值
String propertyValue = properties.getProperty(factoryClassName);
String[] var8 = StringUtils.commaDelimitedListToStringArray(propertyValue);
int var9 = var8.length;
//遍历所有的value,放入结果list中
for(int var10 = 0; var10 < var9; ++var10) {
String factoryName = var8[var10];
result.add(factoryName.trim());
}
}
//返回所有的自动配置类的路径list
return result;
} catch (IOException var12) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var12);
}
}
如HttpEncodingAutoConfiguration
// 是一个配置类,可以往spring容器添加bean对象
@Configuration
// 开启HttpEncodingProperties类的可配置属性功能,即该类的属性与配置文件进行绑定,并将该类添加到ioc容器中,这个类需要使用@ConfigurationProperties声明。
@EnableConfigurationProperties({HttpEncodingProperties.class})
//条件判断:必须是web应用,必须存在CharacterEncodingFilter,即引入了依赖包,需要有spring.http.encoding.enabled的属性,如果没有则默认为true
@ConditionalOnWebApplication
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
//持有一个HttpEncodingProperties类的引用对象
private final HttpEncodingProperties properties;
//只有一个参数为HttpEncodingProperties对象的构造方法,说明此参数是由spring容器确定的,这里一般是由配置文件编写
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
//将方法返回结果注入到spring容器里,id为方法名。只有在容器中不存在这个bean时才进行注入,说明是单例的
@Bean
@ConditionalOnMissingBean({CharacterEncodingFilter.class})
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
}
@ConfigurationProperties(prefix = "spring.http.encoding")
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
}
SpringBoot学习小结的更多相关文章
- springboot 学习小结
springboot 默认自动扫描和配置根包下面的类.如果启动配置不在根包目录下,得把对应的类进行配置扫描生成对应的bean. 主要的扫描注解有: @SpringBootApplication //s ...
- springboot 学习资源推荐
springboot 是什么?对于构建生产就绪的Spring应用程序有一个看法. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.(这是springboot的官方介绍) 我们为什么要学 ...
- flex学习小结
接触到flex一个多月了,今天做一个学习小结.如果有知识错误或者意见不同的地方.欢迎交流指教. 画外音:先说一下,我是怎么接触到flex布局的.对于正在学习的童鞋们,我建议大家没事可以逛逛网站,看看人 ...
- Python 学习小结
python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...
- react学习小结(生命周期- 实例化时期 - 存在期- 销毁时期)
react学习小结 本文是我学习react的阶段性小结,如果看官你是react资深玩家,那么还请就此打住移步他处,如果你想给一些建议和指导,那么还请轻拍~ 目前团队内对react的使用非常普遍,之 ...
- objective-c基础教程——学习小结
objective-c基础教程——学习小结 提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...
- pthread多线程编程的学习小结
pthread多线程编程的学习小结 pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写 程序员必上的开发者服务平台 —— DevSt ...
- ExtJs学习笔记之学习小结LoginDemo
ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...
- 点滴的积累---J2SE学习小结
点滴的积累---J2SE学习小结 什么是J2SE J2SE就是Java2的标准版,主要用于桌面应用软件的编程:包括那些构成Java语言核心的类.比方:数据库连接.接口定义.输入/输出.网络编程. 学习 ...
随机推荐
- yii2中判断值是否存在二维数组中
//在yii2中,在类里面的函数,可以不加action $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); / ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(8)-粒子系统
没有美工的程序员,能够依赖的还有粒子系统. 这一章我们将使用libGDX的粒子系统线性插值以及其他的方法来增加一些特效. 你也可以使用自己编辑的粒子效果,比如这个粒子文件dust:http://fil ...
- python提纲
根据网上专栏整理提纲 1.模块介绍 2.time&datetime模块 3.random模块 4.os模块 5.sys模块 6.json&pickle模块 7.logging模块 8. ...
- Python2.5/2.6实用教程:基础篇(转)
介绍 本文方便有经验的程序员进入Python世界.本文适用于python2.5/2.6版本. Deparecated:Python3 和 python2.x语法不同.如果你正在用python3,请参考 ...
- codeforces 869C The Intriguing Obsession【组合数学+dp+第二类斯特林公式】
C. The Intriguing Obsession time limit per test 1 second memory limit per test 256 megabytes input s ...
- HDU 2045 LELE的RPG难题(递推)
不容易系列之(3)—— LELE的RPG难题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- 洛谷——P1358 扑克牌
题目描述 组合数学是数学的重要组成部分,是一门研究离散对象的科学,它主要研究满足一定条件的组态(也称组合模型)的存在.计数以及构造等方面的问题.组合数学的主要内容有组合计数.组合设计.组合矩阵.组合优 ...
- RabbitMQ (三) 工作队列之轮询分发
上一篇讲了简单队列,实际工作中,这种队列应该很少用到,因为生产者发送消息的耗时一般都很短,但是消费者收到消息后,往往伴随着对高消息的业务逻辑处理,是个耗时的过程,这势必会导致大量的消息积压在一个消费者 ...
- [Luogu P4198]楼房重建(线段树)
题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
- [BZOJ3205][APIO2013]Robot(斯坦纳树)
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 1007 Solved: 240[Submit][Status ...