SpringBoot原理讲解

一.问题的引入

首先我们来看一个最简单的例子。

我们先创建一个SpringBoot的工程,如何创建一个SpringBoot工程就不说了,不会请自行解决。然后写一个controller类,通过请求路径,返回HelloWorld在浏览器页面上显示。

  上面两张图就是程序的一个整体的结构和运行的结果,那么问题来了,SpringBoot程序中没有任何配置,不像Spring框架,写一大堆配置信息在xml文件中,那么程序是怎么将我们这里的Controller类扫描到spring容器中的呢?

二.原理讲解。

首先第一点,我们来看一下SpringBoot的启动类,

package com.example.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class DemoApplication {

    public static void main(String[] args) {

        //启动SpringBoot应用

        SpringApplication.run(DemoApplication.class, args);

    }

}

  

其中,我们看到一个注解@SpringBootApplication,SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

然后我们点进去看看这个注解到底包含了什么,

@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 {

  

其中我们需要重点关注的就是@SpringBootConfiguration、@EnableAutoConfiguration

下面我们逐个来讲解:

@SpringBootConfiguration这个注解顾名思义,标注在某个类上,这个类就是SpringBoot的配置类,我们再点进去看看。

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Configuration

  

原来这个注解是底层是Spring中的注解@Configuration,而@Configuration注解底层就是一个@Component,代表一个容器。

SpringBoot的精髓是在@EnableAutoConfiguration这个注解上,根据名字,我们可以知道这是一个自动配置类,也就是能够实现一些自动配置的功能,那么具体是配置了什么东西呢?

我们再点进去看看

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@AutoConfigurationPackage

@Import(AutoConfigurationImportSelector.class)

  

我们看见了和这个注解有关联的重要的两个注解@AutoConfigurationPackage,@Import(AutoConfigurationImportSelector.class),也是分别给大家讲解一下。

1[email protected]

@AutoConfigurationPackage:这是一个自动配置的包,我们来看下在这个程序中是配置了哪个包,点进来

@Import(AutoConfigurationPackages.Registrar.class)

  

再点到Register,我们看到在大概123行的位置,有一段代码。

@Override

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {

   register(registry, new PackageImport(metadata).getPackageName());

}

  

我们看到这个方法器中一个参数metadata,代表注解的元信息,然后我们通过这个注解的元信息来获这个包名,我们在这打个断点,debug运行,可以看见一些元信息的基本内容,最主要我们要知道是导入了哪个包,我们选中new PackageImport(metadata).getPackageName(),右键计算一下

发现导入的包就是我们项目的根目录,假如我们新建一个包叫com.controller,在里面写一个controller类,大家可以运行的试一下是否能成功呢。

2.@Import(AutoConfigurationImportSelector.class)

     @Import(AutoConfigurationImportSelector.class):这个注解代表的是一个自动配置的选择器,那么要导入哪些组件的选择器呢?

我们点进去,看到非常重要的一段。

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,

      AnnotationMetadata annotationMetadata) {

   if (!isEnabled(annotationMetadata)) {

      return EMPTY_ENTRY;

   }

   AnnotationAttributes attributes = getAttributes(annotationMetadata);

   List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

   configurations = removeDuplicates(configurations);

   Set<String> exclusions = getExclusions(annotationMetadata, attributes);

   checkExcludedClasses(configurations, exclusions);

   configurations.removeAll(exclusions);

   configurations = filter(configurations, autoConfigurationMetadata);

   fireAutoConfigurationImportEvents(configurations, exclusions);

   return new AutoConfigurationEntry(configurations, exclusions);

}

  

这里我们获得到了一个configurations 的list集合,我们打个断点看看这个集合中到底给我们装了些什么东西。

我们发现这个configurations 里面装配了124个自动配置类,原来我们没有配置的一些信息,都通过SpringBoot的自动配置类给我配置好了。

那么我还想知道这些类SpringBoot程序给我们放到哪了呢,我们看到getCandidateConfigurations(annotationMetadata, attributes);

点进去,我们看到:

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass()

  

那么再点进去我们看看到底加载的工厂名称是啥,

try {

   Enumeration<URL> urls = (classLoader != null ?

         classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

         ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

   result = new LinkedMultiValueMap<>();

   while (urls.hasMoreElements()) {

      URL url = urls.nextElement();

      UrlResource resource = new UrlResource(url);

      Properties properties = PropertiesLoaderUtils.loadProperties(resource);

      for (Map.Entry<?, ?> entry : properties.entrySet()) {

         String factoryTypeName = ((String) entry.getKey()).trim();

         for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {

            result.add(factoryTypeName, factoryImplementationName.trim());

         }

      }

   }

  

我们看到其中类加载器给我们获取了资源,我们点进去,

点了这么多次,终于找到我们想要的答案了!!!

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

  

原来这些自动配置类都在类路径下的"META-INF/spring.factories"

还有下面的autoconfigure包中的内容,我们也看看

这里面我们所有所用到的配置类全部由SpringBoot给我们配置了,所以我们知道SpringBoot表面上是零配置的,其实底层都给我们封装好了,也是方便我们程序员进行开发。

那么有些人肯定又有疑惑,SpringBoot怎么知道给我们自动配置哪些类呢?

欲知后事如何,请关注一下作者,纯手打码字不易,也是希望和大家多多交流,一起学习,谢谢!

原文地址:https://www.cnblogs.com/wujunstart/p/12015895.html

时间: 2024-08-29 19:06:33

SpringBoot原理讲解的相关文章

联营合营企业顺逆流交易在合并报表中抵消分录的原理讲解

下面通过两道例题来讲解一下处理原理: 逆流交易:例题:甲公司2012年1月1日取得乙公司20%有表决权股份,能够对乙公司施加重大影响.假定甲公司取得该项投资时,乙公司各项资产.负债的账面价值等于公允价值.2012年11月,乙公司将其成本为1200万元的商品以1800万元的价格出售给甲公司,甲公司将其取得的商品作为存货.至2012年12月31日,甲公司未对外出售该批存货.乙公司2012年实现净利润3200万元,假定不考虑所得税因素影响.先对个别报表分录进行分析:甲公司在按照权益法确认应享有乙公司2

SQL注入原理讲解,很不错!

SQL注入原理讲解,很不错! 原文地址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码被流传于网络,连日来引发众多网民对自己账号.密码等互联网信息被盗取的普遍担忧. 网络安全成为了现在互联网的焦点,这也恰恰触动了每一位用户的神经,由于设计的漏洞导致了不可收拾的恶果,验证了一句话

XSS测试用例与原理讲解

1.<a href="javascript:alert(32)">DIBRG</a>2.<img href="javascript:alert(32)">   在IE下可以,在FF下不可以3.<img src=" http://xss.jpg" onerror=alert('XSS')>     IE,FF下均可4.<img STYLE="background-image: url(

仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解

先看效果 分别是我的效果和今日头条的效果: 以上效果包括: 1.如果下拉的高度超过search view的高度的3/4,但是小于head view高度,则松开手时search view自动出现 2.如果下拉的高度小于search view的高度的1/4,则松开手时search view自动回弹消失 3.如果下拉的高度超过head view的总高度,则松手进行刷新 4.刷新完成自动隐藏search view 实现原理讲解 参考了 github开源项目:[https://github.com/viv

Memcached初体验及原理讲解

1.简介 Memcached 是一个 高性能的 分布式 内存对象缓存系统,用于动态Web应用减少数据库负载,提升性能. 2.试用场景 1.变化频繁,具有不稳定性的数据 (比如用户在线状态.在线人数..) 2.门户网站的新闻等,觉得页面静态化仍不能满足要求,可以放入到memcache中. 什么样的数据不适合放入memcached中?(银行,股票,证券系统.) 过大的数据不能放入到memcache(优酷网.) --我自己的一个小结如何决定是否使用memcached --如果是一个小网站,pv值不大,

机器学习:梯度下降算法原理讲解

背景 学习机器学习时作为基础概念. 转载自: <梯度下降算法原理讲解--机器学习> 1. 概述 梯度下降(gradient descent)在机器学习中应用十分的广泛,不论是在线性回归还是Logistic回归中,它的主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值. 本文将从一个下山的场景开始,先提出梯度下降算法的基本思想,进而从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后实现一个简单的梯度下降算法的实例! 2. 梯度下降算法 2.1 场景假设 梯度下降法的基本思想可以类比为

SpringBoot原理分析与配置

1.1 起步依赖原理分析 1.1.1 分析spring-boot-starter-parent 按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下(只摘抄了部分重点配置): <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-de

十种MYSQL显错注入原理讲解(二)

上一篇讲过,三种MYSQL显错注入原理.下面我继续讲解. 1.geometrycollection() select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b)); 函数讲解: GeometryCollection是由1个或多个任意类几何对象构成的几何对象.GeometryCollection中的所有元素必须具有相同的空间参考系(即相同的坐标系).对Ge

OAuth的机制原理讲解及开发流程 (转)

本想前段时间就把自己通过QQ OAuth1.0.OAuth2.0协议进行验证而实现QQ登录的心得及Demo实例分享给大家,可一直很忙,今天抽点时间说下OAuth1.0协议原理,及讲解下QQ对于Oauth1.0的认证开发.闲话多说了点,下面直接进入主题. 1.OAuth的简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的.(我喜欢简单明了,这里没看懂,没关系,