基于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学习小结的更多相关文章

  1. springboot 学习小结

    springboot 默认自动扫描和配置根包下面的类.如果启动配置不在根包目录下,得把对应的类进行配置扫描生成对应的bean. 主要的扫描注解有: @SpringBootApplication //s ...

  2. springboot 学习资源推荐

    springboot 是什么?对于构建生产就绪的Spring应用程序有一个看法. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.(这是springboot的官方介绍) 我们为什么要学 ...

  3. flex学习小结

    接触到flex一个多月了,今天做一个学习小结.如果有知识错误或者意见不同的地方.欢迎交流指教. 画外音:先说一下,我是怎么接触到flex布局的.对于正在学习的童鞋们,我建议大家没事可以逛逛网站,看看人 ...

  4. Python 学习小结

    python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...

  5. react学习小结(生命周期- 实例化时期 - 存在期- 销毁时期)

    react学习小结   本文是我学习react的阶段性小结,如果看官你是react资深玩家,那么还请就此打住移步他处,如果你想给一些建议和指导,那么还请轻拍~ 目前团队内对react的使用非常普遍,之 ...

  6. objective-c基础教程——学习小结

    objective-c基础教程——学习小结   提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...

  7. pthread多线程编程的学习小结

    pthread多线程编程的学习小结  pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写     程序员必上的开发者服务平台 —— DevSt ...

  8. ExtJs学习笔记之学习小结LoginDemo

    ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  9. 点滴的积累---J2SE学习小结

    点滴的积累---J2SE学习小结 什么是J2SE J2SE就是Java2的标准版,主要用于桌面应用软件的编程:包括那些构成Java语言核心的类.比方:数据库连接.接口定义.输入/输出.网络编程. 学习 ...

随机推荐

  1. 【转】C#获取当前程序运行路径的方法集合

    //获取当前进程的完整路径,包含文件名(进程名).string str = this.GetType().Assembly.Location;result: X:\xxx\xxx\xxx.exe (. ...

  2. [libgdx游戏开发教程]使用Libgdx进行游戏开发(9)-场景过渡

    本章主要讲解场景过渡效果的使用.这里将用到Render to Texture(RTT)技术. Libgdx提供了一个类,实现了各种常见的插值算法,不仅适合过渡效果,也适合任意特定行为. 在本游戏里面, ...

  3. sublime text3插件TrailingSpaces无法使用的解决方法

    TrailingSpaces是很好用的一款插件,可以清除代码结尾打多了几个空格或Tab,对于代码洁癖绝对是个福音,我的sublime text3本来安装了这款插件,也可以正常使用,今天突然不能用了,即 ...

  4. C3P0连接池一些基本配置

    C3P0连接池配置 数据库连接是一个耗费大量资源且相当慢的操作,所以为了提高性能和连接速度,诞生了连接池这样的概念. 在多用户并发操作过程中,连接池尤为重要. 它是将那些已连接的数据库连接存放在一个容 ...

  5. 22、Django实战第22天:课程评论

    1.编辑course-comment.html 2.编辑courses.views.py class CourseCommentView(LoginRequiredMixin, View): def ...

  6. URAL 2062 Ambitious Experiment(分块)

    [题目链接] http://acm.timus.ru/problem.aspx?space=1&num=2062 [题目大意] 给出两个操作,操作一给出区间[l,r],对l到r中的每一个下标i ...

  7. 【2-SAT】【并查集】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem

    再来回顾一下2-SAT,把每个点拆点为是和非两个点,如果a能一定推出非b,则a->非b,其他情况同理. 然后跑强连通分量分解,保证a和非a不在同一个分量里面. 这题由于你建完图发现都是双向边,所 ...

  8. SSH学习——Spring基础

    1.理解什么是Spring框架? spring是J2EE应用程序框架,是轻量级的IOC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框 ...

  9. Asp.Net MVC part3 路由Route

    路由Route路由规则Route:可以查看源代码了解一下构造方法,需要指定路由格式.默认值.处理器三个值路由数据RouteData:当前请求上下文匹配路由规则而得到的一个对象,可以在Action中通过 ...

  10. Word调整表格大小

    在Word文档中创建表格后,用户往往需要根据输入的内容调整表格的行高和列宽,有时也需要对整个表格的大小进行调整. 在选择的表格上右击,选择快捷菜单中的“自动调整”—“根据内容调整表格”命令,Word将 ...