• J3
  • SpringBoot # 源码 # 自动装配

一日我在愉快得遨游时,看到有鱼友在问:SpringBoot 中引入了 Nacos 依赖为啥就可以直接使用 Nacos 中的相关功能呀!

认真思考了一番,我立马就想说,自动装配,但这种回答怎么能体现我的牛逼呢!(牛逼症犯了)

思索万千,我给出了下面的回答:因为 SpringBoot 的宗旨是,约定大于配置,一切都由约定所决定。当你引入 Nacos 的依赖时,就和 SpringBoot 达成了一个约定环境中需要有 Nacos 相关功能,所以 SpringBoot 就在启动的时候将 Nacos 中所需要的功能自动装配好了。

洋洋洒洒一段话抛出,然而并没有达到那种溅起千层浪花的效果,反倒是下面的一句句”这就是 SpringBoot 的自动装配“ 来的效果好。

what?

早知道他们都是那么简单的人,我又何必装深沉,小丑竟然是我自己。

既然提到了自动装配,而日常工作中基本离不开 SpringBoot 并且自动装配又是 SpringBoot 中的一个重要功能,那我有什么理由不去深入研究一番呢!

我常教导你们要扒光内裤看个究竟,今天咱就来扒一扒自动装配的功能始末。

说明

  1. JDK为 1.8
  2. SpringBoot 为 2.5.5

1、手写一个 Starter

在分析之前,我认为有必要先手动实现一个 Starter 。因为自动装配这个功能我们要理解它到底是在自动装配个什么东西,对吧!

很简单,就是自动装配我们引入的一个个 Starter 。那是什么 Starter 都能够被装配嘛,我写个 Hello World 它也能给我自动装配?

当然是什么都能够自动装配了,但前提是我们编写的 Starter 必须要符合 SpringBoot 的自动装配规则,否则是不行的,那到底是什么规则呢!

1、在 resources/META-INF 目录下必须要有 spring.factories

2、spring.factories 文件中必须要有 org.springframework.boot.autoconfigure.EnableAutoConfiguration 对应的配置类

3、要被使用的 Bean 必须正常被扫描到

ok,了解这么多那就开始手写一个 Starter 。

1.1 先创建一个 SpringBoot 项目

项目可以不需要启动类,因为本来也没打算让他运行,项目目录结构如下:

MyStarterApplication:主配置类。

spring.factories(重点):配置文件,告知 SpringBoot 要装配的配置类在哪。

MyStarterService:业务类。

1、MyStarterApplication

// 扫描规则,将要被管理的 Bean 交给 IOC 容器
@ComponentScan("cn.j3.mystarter")
public class MyStarterApplication {// 配置
}

2、spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.j3.mystarter.MyStarterApplication

3、MyStarterService

@Service
public class MyStarterService {public void myService(String example) {System.out.println("您传入得值为:" + example);}
}

ok,就这点东西一个 Starter 就算是写好了,下面我们就在另外一个项目中引入这个项目依赖,并启动另外一个项目,最终可以发现 MyStarterService 业务类可以正常使用。

另一个项目 pom 文件引入下面依赖:

<dependency><groupId>cn.j3</groupId><artifactId>my-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>

测试 controller

@RestController
@RequestMapping("/test")
public class MvcTestController {// 正常注入@Autowiredprivate MyStarterService myStarterService;@GetMapping("/mvc")public String mvcTest(){System.out.println("mvc success!");// 正常调用myStarterService.myService("测试自动装配!");return "success!";}
}

控制台输出

mvc success!
您传入得值为:测试自动装配!

自定义 starter 编写完成,是不是觉得非常简单。

2、探究自动装配原理

上面我们自定义的 starter 生效的过程就是 SpringBoot 自动装配的过程,因为我们只是在一个项目中引入了我们自定义的 starter 而里面的功能就可以生效。

那我们先来分析一下自定义的 starter 。

在 SpringBoot 中要想让一个功能被 IOC 容器管理我们应该怎么做,对,就是让类被 SpringBoot 扫描到并放入容器中。

在我们自定义的 starter 中我们可以看到这样的一个配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.j3.mystarter.MyStarterApplication

这是核心,它是功能生效的源头。

因为我们有了上面的配置,使得 MyStarterApplication 类成为了 SpringBoot 的一个配置类当配置类被加载到容器中时,配置类上的注解从而就生效,进而带动了整个 starter 中的 Bean 都被容器所管理。

那源头我们是找到了,就是 spring.factories 文件,只要配置的这个文件生效,starter 就会生效。

所以 spring.factories 文件是如何生效的呢!

这里我说结果把!就是 @SpringBootApplication 这个注解。可以说,在整个 SpringBoot 中这个注解是非常重要,如果没有它,那么像自动装配、包扫描等功能都会失效,所以本次我们分析源码的入口就是这个注解了。

在我们步步为营,层层递进的情况下,终于是分析到了 @SpringBootApplication 注解,可喜可贺!

2.1 @SpringBootApplication

这个注解不用我多说,大伙也都知道它在哪吧!—— 主类

// 我们要分析的注解
@SpringBootApplication
public class StudySpringbootApplication {public static void main(String[] args) {SpringApplication.run(StudySpringbootApplication.class, args);}
}

在 IDEA 中点进这个注解看看它的源码:

@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 {@AliasFor(annotation = EnableAutoConfiguration.class)Class<?>[] exclude() default {};@AliasFor(annotation = EnableAutoConfiguration.class)String[] excludeName() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")String[] scanBasePackages() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

简单的说一下这个注解所包含的源码功能

  1. @SpringBootConfiguration:标注的类为 SpringBoot 的一个配置类
  2. @EnableAutoConfiguration:自动配置注解(重点!!!!!!!!!)
  3. @ComponentScan:包扫描注解
  4. 注解属性主要是定义了排除一些不用装配的类,根据 Class 、name 等规则进行排除
  5. 激活 @Component 扫描的 @ComponentScan

很明显我们接下来要分析的重点是 @EnableAutoConfiguration 注解

2.2 @EnableAutoConfiguration

看名字我们就能猜出这个注解的作用:开启自动配置。它位于 spring-boot-autoconfigure 包内,当我们使用 @SpringBootApplication 注解时,它就会自动生效。

下面来看看它的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// 用来覆盖配置开启 / 关闭自动配置的功能String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";// 根据类排除指定的自动配置Class<?>[] exclude() default {};// 根据类名排除指定的自动配置String[] excludeName() default {};
}

对于 @EnableAutoConfiguration 注解的属性大伙看我标注的注释就行,但我们还看到这个注解式又标注了其它两个注解分别为:

  1. @AutoConfigurationPackage
  2. @Import(AutoConfigurationImportSelector.class)

@AutoConfigurationPackage 注解的功能我就简单说一下,将注解所在的包路径加入到一个专门记录packageNames的集合里,那至于为啥加到这个集合里,我想就是为了包扫描吧!

下面就是 @Import 注解了,在学习 Spring 的时候我们也经常使用 标签,不知道大家还有没有印象了。这个注解的作用就是向项目中导入什么什么配置类的功能,它位于 spring-context 包内,所以它在这里的所用是,向项目中导入了 AutoConfigurationImportSelector 配置类。

2.3 AutoConfigurationImportSelector

先来看看这个类的继承关系图:

咋一看这个类实现的接口还挺多的,其实就两大类

  1. ImportSelector 类接口
  2. Aware 类接口

先说第一类,AutoConfigurationImportSelector 并没有直接实现 ImportSelector 接口而是其子接口 DeferredImportSelector 接口,那这两个接口有什么区别吗?DeferredImportSelector 接口会在所有的 @Configuration 类加载完成之后在加载返回的配置类,而 ImportSelector 是在加载完 @Configuration 之前先去加载返回的配置类。

第二类,XXXAware 类接口则是在 Bean 实例化的时候为其传入相关的环境对象,如 BeanFactory 、Environment 、ResourceLoader 等。

在 Spring 中它会保证在执行 ImportSelector 接口的方法之前,先执行 XXXAware 接口的方法,保证对应的属性都被附上对应的值。

那现在回到接口 ImportSelector 它是干什么的,又是在什么时候被执行的。

接口源码:

public interface ImportSelector {// 根据导入的Configuration类的注解元数据选择哪一个类需要被导入,返回的数组就是需要被导入的类名String[] selectImports(AnnotationMetadata importingClassMetadata);// 排除不需要导入的类@Nullabledefault Predicate<String> getExclusionFilter() {return null;}
}

接口只是定义了规范,selectImports 方法的具体实现在 AutoConfigurationImportSelector 类中,我们来看看实现源码:

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 检查自动配置功能是否开启,默认开启if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}// 封装将被引入的自动配置信息AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);// 返回符合条件的配置类的全限定类名数组return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

看到这里,我们知道 getAutoConfigurationEntry(annotationMetadata) 方法就是我们要深入研究的点,因为它返回的是所有需要自动配置的全限定类名,只有把这个返回给了 SpringBoot ,它才知道需要自动装配那些功能。

至于何时执行这段代码,我也是 Debug 的时候才搞明白个所以然

还记得我们之前提到的 ImportSelector 和 DeferredImportSelector 的区别吗?因为我们的 AutoConfigurationImportSelector 类实现的是后者,所以程序在执行的时候不会去执行 selectImports 方法,而是会去执行其静态内部类 AutoConfigurationGroup 中的 process 方法并且最终会调到 getAutoConfigurationEntry 方法获取到所有的自动装配类。

至于为什么是从 org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup # process 调进来,在这里不做过多的分析,不是本次的重点,下面分析自动装配的类是如何被加载进来的。

2.3.1 getAutoConfigurationEntry

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {// 是否开启自动装配if (!isEnabled(annotationMetadata)) {// 未开启,返回空return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);// 通过 SpringFactoriesLoader 类提供的方法加载类路径中 META-INF 目录下的 spring.factories 文件中针对 EnableAutoConfiguration 的注册配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 队获得的注册配置类集合进行去重处理,防止多个项目引入同样的配置类configurations = removeDuplicates(configurations);// 获得注解中被 exclude 或 excludeName 所派出的类的集合Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 检查被排除类是否可实例化,是否被自动注册配置所使用,不符合条件则抛出异常checkExcludedClasses(configurations, exclusions);// 从自动配置类集合中取出被排除的类configurations.removeAll(exclusions);// 检查配置类的注解是否符合 spring.factories 文件中 AutoConfigurationImportFilter 指定的注解检查条件configurations = getConfigurationClassFilter().filter(configurations);// 将赛选完成的配置类和排查的配置类构建为事件类,并传入监听器。监听器的配置在于 spring.factories 文件中,通过 AutoConfigurationImportListener zfireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}

通过这段代码注释,我们可以从整体上了解获取自动装配类的概况及操作流程,下面我会对这些流程做细致的分析。

首先是自动装配开关功能,很好理解,SpringBoot 给我们预留了 spring.boot.enableautoconfiguration = true/false 这一配置项来控制是否开启自动装配功能,默认是开启。

下面来到这行代码:getAttributes(annotationMetadata)

这行代码的作用就是获取到主类中配置的 exclude 、 excludeName 两个属性的值,为了对后面读出的自动装配类做排除作用,排除这些指定不需要装配的类。

继续分析这行代码:getCandidateConfigurations(annotationMetadata, attributes)

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 重点,获取 META-INF/spring.factories 文件中 EnableAutoConfiguration 类型的值List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),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;
}

SpringFactoriesLoader 是 Spring-Core 提供的一个工具类,它是专门读取 META-INF/spring.factories 文件中相关值得功能,比如 loadFactoryNames 方法,如果向其传入 EnableAutoConfiguration. Class 类型的值,那它就会读取下面这部分的值:

这里说明一点的是,它会读取所有依赖包下 META-INF/spring.factories 文件的值,如果大家 Debug 的话可以看到我们自定义 starter 中自动装配类也是被加载进来了,如图:

注意:loadFactoryNames 方法是根据传入的类型去读取对应的值,所以在读取 spring.factories 文件值时,它是一个通用方法。

下面接着分析这个方法:removeDuplicates(configurations)

这句代码非常简单,我是不想贴代码了。它的作用是去重,因为 getCandidateConfigurations 是加载所用依赖包下的自动装配类,难保这些依赖包不会引入重复的自动装配类,所以这里要将重复的类进行排除。排除方法也是很简单,使用 Set 结构的特性进行排除。

接着看下面这个方法:getExclusions(annotationMetadata, attributes)

protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {Set<String> excluded = new LinkedHashSet<>();// 排除配置的自动装配类excluded.addAll(asList(attributes, "exclude"));excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));// 排除通过配置文件 spring.autoconfigure.exclude = 类,的方法进行排除excluded.addAll(getExcludeAutoConfigurationsProperty());return excluded;
}

上面说过 attributes 是主类中配置的需要移除的自动装配类,而 getExcludeAutoConfigurationsProperty 则是通过 spring.autoconfigure.exclude = 全限定类名 的方式排除,所以这个方法的作用就是返回主类中配置的和 spring.autoconfigure.exclude 配置的需要排除的自动装配类。

在获取了需要排除的自动装配类之后则是需要对这些排除类进行检查,检查排除的类是否属于当前 ClassLoad 和不存在于需要自动装配类的集合中,如果条件满足,那就要报错了。

检查通过后,就是排除了,代码体现是这个:configurations.removeAll(exclusions) ,常规的集合操作,就不过多讲了。

至此呢,自动装配的初步功能算是完成了,我总结一下初步功能干了些啥:

  1. 判断是否需要自动装配
  2. 加载所有包下的 META-INF/spring.factories 文件中 EnableAutoConfiguration. Class 类型的值
  3. 获取需要排除的自动装配类集合
  4. 检查需要排除的自动装配类是否符合排除要求
  5. 对加载的自动装配类集合进行排除

SpringBoot 后续还要判断那些自动装配的类需要起作用,总不至于所有的配置都生效吧!所以往下看。

2.4 过滤自动装配

正如上面说的那样,加载的自动装配类不可能全部都生效,所以要在下面这行代码处进行过滤,将那些不需要生效的自动装配剔除掉。

configurations = getConfigurationClassFilter().filter(configurations);

这行代码分为两部分:

  1. 获取过滤器
  2. 执行过滤器的过滤方法

先来说说第一部分,getConfigurationClassFilter() 方法主要是获取 META-INF/spring.factories 文件中配置了 key 为 org.springframework.boot.autoconfigure.AutoConfigurationImportFilter 的值,并封装成 ConfigurationClassFilter 对象返回出去,源码如下。

private ConfigurationClassFilter getConfigurationClassFilter() {if (this.configurationClassFilter == null) {// 加载文件中的过滤器List<AutoConfigurationImportFilter> filters = getAutoConfigurationImportFilters();for (AutoConfigurationImportFilter filter : filters) {// 给过滤器配置相应的环境属性值,可以认为是初始化过滤器的一些属性值invokeAwareMethods(filter);}// 封装过滤器配置对象this.configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);}return this.configurationClassFilter;
}
// 具体的加载 META-INF/spring.factories 中的 AutoConfigurationImportFilter 值
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
}

如图,SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader) 获取的是文件中这部分的值:

再来说说第二部分,在第一部分中获取了所有的过滤器之后给我们返回了 ConfigurationClassFilter 对象,然后在调用他的 filter 方法进行过滤的,那我们就来看看这个方法的源码。

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.ConfigurationClassFilter # filter

List<String> filter(List<String> configurations) {long startTime = System.nanoTime();// 将所有加载的自动配置类封装成数组String[] candidates = StringUtils.toStringArray(configurations);boolean skipped = false;// 挨个遍历过滤器进行判断,自动装配是否生效for (AutoConfigurationImportFilter filter : this.filters) {// 这是判断生效逻辑,candidates 是自动装配类数组,this.autoConfigurationMetadata 这个是 META-INF/spring-autoconfigure-metadata.properties 文件中的值boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);for (int i = 0; i < match.length; i++) {if (!match[i]) {// 将不生效的自动配置类替换为 null 值candidates[i] = null;// 这个是一个标志位,保证下面需要进行剔除skipped = true;}}}// 判断标志位,有改动,说明要往下走,如果没有改动那就全部生效,不进行剔除if (!skipped) {return configurations;}// 剔除操作List<String> result = new ArrayList<>(candidates.length);// 遍历所有的自动装配类数组for (String candidate : candidates) {// 将不为 null 的值返回出去if (candidate != null) {result.add(candidate);}}if (logger.isTraceEnabled()) {int numberFiltered = configurations.size() - result.size();logger.trace("Filtered " + numberFiltered + " auto configuration class in "+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");}// 最终需要自动装配类的集合return result;
}

这一段是判断自动装配类是否生效的核心代码,而主要的判断逻辑则是 match 方法

从代码我中我们可以看到调用的是 AutoConfigurationImportFilter 类的 match 方法,那我们来看看它的类继承结构图。

  • AutoConfigurationImportFilter :定义了 match 方法的函数式接口。
  • FilteringSpringBootCondition : match 方法的直接实现类。
  • OnBeanCondition :具体过滤器,其实 match 中会调用每个具体过滤器中的 getOutcomes 方法判断生效逻辑。
  • OnClassCondition :具体过滤器,其实 match 中会调用每个具体过滤器中的 getOutcomes 方法判断生效逻辑。
  • OnWebApplicationCondition :具体过滤器,其实 match 中会调用每个具体过滤器中的 getOutcomes 方法判断生效逻辑。

我们知道 match 是被 getConfigurationClassFilter 方法加载出来的具体过滤器进行调用的,再结合上面我介绍 AutoConfigurationImportFilter 类结构体可知,最终判断生效的逻辑出自过滤器中的 getOutcomes 方法。

因为每个过滤器都有对应的 getOutcomes 处理逻辑,所以就不贴这个方法的代码了,但万变不离其宗,所有的处理逻辑都是通过判断自动装配类 + ”.“ + OnBeanCondition 或 OnClassCondition 或 OnWebApplicationCondition 形成 key 去 this.autoConfigurationMetadata 集合中找对应的值,如果没有找到则默认加载反之则将获取到的值通过加载器进行加载,加载成功则自动装配类生效反之则不生效过滤掉,最终会返回一个对应自动装配类集合的 true / false 数组。

至此,我们的 match 方法就分析结束了,它最终返回的是和自动装配类集合对应的 true / false 集合,对应位置的值为 true 说明自动装配类集合中对应的自动装配类生效。

2.5 事件封装和广播

上面我们已经分析出了自动装配需要生效的自动装配全限定类名集合了,但还没完呢!

getAutoConfigurationEntry 方法还有最后一行代码:fireAutoConfigurationImportEvents(configurations, exclusions) 。

下面来看看它的源码:

private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {// 加载 META-INF/spring.factories 文件中类型为 AutoConfigurationImportListener 的监听器,List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners();if (!listeners.isEmpty()) {// 封装自动装配导入事件,AutoConfigurationImportEventAutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);// 遍历监听器for (AutoConfigurationImportListener listener : listeners) {invokeAwareMethods(listener);// 广播事件,所有监听 AutoConfigurationImportEvent 事件的都会做出相关的反应listener.onAutoConfigurationImportEvent(event);}}
}

对于事件监听和广播不是我们分析的重点,而这里再加载完自动配置类之后就是做了一个事件广播。将生效的自动配置类和被排除的自动装配类封装成事件向外广播,当遇到对这件事感兴趣的监听器就会做出相关的反应。

META-INF/spring.factories 文件中类型为 AutoConfigurationImportListener 的监听器如下:

3、最后

对于 SpringBoot 的自动装配我由浅入深的分析了其整个的运行流程,整体来说偏向简单没有晦涩难懂的代码。大家可以对着本篇讲解的步骤自己手动 Debug 几次相信掌握它不成问题,最后附上自动装配核心代码的处理逻辑流程图,便于整体理解。

好了,今天的内容到这里就结束了,关注我,我们下期见

有任何问题,根据下面联系方式找到我:

QQ:1491989462

微信:13207920596


  • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。
  • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。
  • 感谢您的阅读,十分欢迎并感谢您的关注。

刨析 SpringBoot 自动装配原理,其实很简单相关推荐

  1. SpringBoot自动装配原理浅析

    Springboot自动装配原理 SpringBoot是当下J2EE最为流行的框架,它有着轻量,快捷等特点,让程序员们可以专注在业务逻辑的编写上,而不用花太多的力气在一些环境的配置,整合组件的配置上面 ...

  2. 【理解springboot自动装配原理】

    理解springboot自动装配原理: 最近读了小马哥(mercyblitz)Springboot编程思想(核心篇),有了一些心得和感悟,分享给大家: 1. 官网介绍了激活自动装配的方法: * 文档提 ...

  3. 面试终极宝典:Springboot自动装配原理

    Springboot的自动装配过程,网上大多都是罗列代码,即使看完了,也还存在很多的疑点.下面,这是我总结的在面试过程中介绍SpringBoot自动装配原理的话术,拿来即用就可. Springboot ...

  4. 淘宝(SpringBoot自动装配原理)

    什么是 SpringBoot 自动装配 通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能 SpringBoot 是如何实现自动装配的 SpringBoot 的核心注解 S ...

  5. SpringBoot 自动装配原理

    运行原理探究 我们之前写的HelloSpringBoot,到底是怎么运行的呢,Maven项目,我们一般从pom.xml文件探究起: 1.父依赖 pom.xml spring-boot-dependen ...

  6. springboot自动装配原理笔记一

    思维导图 太长放不了截图,就看大纲吧. 从启动类的@SpringBootApplication注解开始,探究其自动装配的原理 结论 整合javaEE,解决方案和自动装配的东西都在spring-boot ...

  7. SpringBoot 自动装配原理解析

    自动装配是 Spring Boot 的核心部分,也是 Spring Boot 功能的基础,正是由于自动装配,才 将我们从 Bean 的繁复配置中解脱出来.那么 Spring Boot 中的自动装配指的 ...

  8. SpringBoot自动装配原理解析——面试可以这样会回答

    1. 前言 SpringBoot是目前软件中最主流的框架,无论是工作还是面试基本都有它的身影,SpringBoot主要解决了传统spring的重量级xml配置Bean,实现了自动装配:所以,我们也常在 ...

  9. 面试题总结(mybatis一级缓存及二级缓存、springboot自动装配原理等)

    1.mybatis一级缓存及二级缓存 区别: 一级缓存的作用域是一个sqlsession内: 二级缓存作用域是针对mapper(Namespace)进行缓存: 一级缓存: 在参数和SQL完全一样的情况 ...

最新文章

  1. .NetCore Winform控制台 做HTTP Host,简易接口
  2. spring 入门 1
  3. zip unzip_zip和unzip上的Java要点
  4. Oracle中计算两个时间的时间差:
  5. python实战===生成随机数
  6. ffmpeg实现摄像头拉流_干货 | 速看!乐橙K32Famp;K36F摄像头全彩夜视功能的不同点全在这了!...
  7. LeetCode 1 两数之和 python
  8. 怎样快速学习shell语言
  9. (转)比特币核心钱包(Bitcoin Core)入门使用教程
  10. C语言:表白(多彩小心心)
  11. Linux efi分区被删除了,如何恢复意外删掉的EFI系统分区
  12. python停止程序_如何停止python程序
  13. AI助力智能安检,基于目标检测模型实现X光安检图像智能检测分析
  14. 数字电路3(逻辑函数的卡诺图化简法)
  15. 我的(此)电脑里面除了磁盘以外,多了一个CD驱动器,删除方法,亲测有效
  16. 【知识图谱】实践篇——基于医疗知识图谱的问答系统实践(Part2):图谱数据准备与导入
  17. 实体、协议、服务和服务访问点的概念
  18. GeneXus学习记录——Transaction
  19. Windows Defender 防病毒发现威胁;关闭;
  20. 协和医院(东单院区)就诊流程记录

热门文章

  1. 科技英语计算机单元答案,科技英语课后练习答案.doc
  2. FDFS_Ubuntu部署fdfs测试上传文件不成功
  3. 线性代数让我想想:什么是秩?
  4. 常微分方程中混合边界及狄利克雷边界条件下的Shooting method以及Finite difference method
  5. 【其他】Switch电脑注入大气层
  6. 杭电oj ——1000 A+B问题
  7. 【图像分割】基于snake模型的图像分割matlab 源码
  8. 树莓派使用FlashFxp SSH 连接
  9. 国科大学习资料--模式识别与机器学习(黄庆明)--期末复习题4(含答案)
  10. 计算机毕业设计情况进展记录表,毕业设计(论文)中期检查记录表