SpringBoot自动配置特点与原理详细分析

作者:崇令 时间:2023-11-19 19:15:01 

一、SpringBoot是什么

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。

在Spring框架这个大家族中,产生了很多衍生框架,比如 Spring、SpringMvc框架等,Spring的核心内容在于控制反转(IOC)和依赖注入(DI),所谓控制反转并非是一种技术,而是一种思想,在操作方面是指在spring配置文件中创建<bean>,依赖注入即为由spring容器为应用程序的某个对象提供资源,比如 引用对象、常量数据等。

在Spring框架这个大家族中,产生了很多衍生框架,比如 Spring、SpringMvc框架等,Spring的核心内容在于控制反转(IOC)和依赖注入(DI),所谓控制反转并非是一种技术,而是一种思想,在操作方面是指在spring配置文件中创建<bean>,依赖注入即为由spring容器为应用程序的某个对象提供资源,比如 引用对象、常量数据等。

二、SpringBoot的特点(核心功能)

  • 可独立运行的Spring项目:Spring Boot可以以jar包的形式独立运行。

  • 内嵌的Servlet容器:Spring Boot可以选择内嵌Tomcat、Jetty或者Undertow,无须以war包形式部署项目。

  • 简化的Maven配置:Spring提供推荐的基础 POM 文件来简化Maven 配置。

  • 自动配置Spring:Spring Boot会根据项目依赖来自动配置Spring 框架,极大地减少项目要使用的配置。

  • 提供生产就绪型功能:提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查。

  • 无代码生成和xml配置:Spring Boot不生成代码。完全不需要任何xml配置即可实现Spring的所有配置。

SpringBoot最明显的特点是,让文件配置变的相当简单、让应用部署变的简单(SpringBoot内置服务器,并装备启动类代码),可以快速开启一个Web容器进行开发。

三、SpringBoot的自动配置原理

Spring Boot的启动类上有一个@SpringBootApplication注解,这个注解是Spring Boot项目必不可少的注解。

1. @SpringBootApplication

作用:SpringBoot的核心注解,标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用

@SpringBootApplication
public class Springboot01Application {
   public static void main(String[] args) {
      SpringApplication.run(Springboot01Application.class, args);
   }
}

它的本质是一个组合注解,我们点进去查看该类的元信息主要包含3个注解:

@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}
)}
)

2. @SpringBootConfiguration

作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;我们继续进去这个注解查看源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
   @AliasFor(
       annotation = Configuration.class
   )
   boolean proxyBeanMethods() default true;
}

@Configuration标注在某个类上,表示这是一个 springboot的配置类。可以向容器中注入组件。

3. @EnableAutoConfiguration

作用:开启自动配置功能

以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;

点进注解接续查看:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {

@AutoConfigurationPackage:自动配置包

@Import({AutoConfigurationImportSelector.class}):Spring底层注解@import , 给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class这个类来指定

①利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件;

②调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类;

③利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件;

④从META-INF/spring.factories位置来加载一个文件。默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件。

4. @ComponentScan

作用:自动扫描组件,默认扫描该类所在包及其子包下所有带有指定注解的类,将它们自动装配到bean容器中,会被自动装配的注解包括@Controller、@Service、@Component、@Repository等。也可以指定扫描路径。

四、核心原理图

SpringBoot自动配置特点与原理详细分析

简单来说,Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。

五、常用的Conditional注解

在加载自动配置类的时候,并不是将spring.factories的配置全部加载进来,而是通过@Conditional等注解的判断进行动态加载;

@Conditional其实是spring底层注解,意思就是根据不同的条件,来进行自己不同的条件判断,如果满足指定的条件,那么配置类里边的配置才会生效;

常用的Conditional注解:

@ConditionalOnClass : classpath中存在该类时起效

@ConditionalOnMissingClass : classpath中不存在该类时起效

@ConditionalOnBean : DI容器中存在该类型Bean时起效

@ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效

@ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效

@ConditionalOnExpression : SpEL表达式结果为true时

@ConditionalOnProperty : 参数设置或者值一致时起效

@ConditionalOnResource : 指定的文件存在时起效

@ConditionalOnJndi : 指定的JNDI存在时起效

@ConditionalOnJava : 指定的Java版本存在时起效

@ConditionalOnWebApplication : Web应用环境下起效

@ConditionalOnNotWebApplication : 非Web应用环境下起效

来源:https://blog.csdn.net/m0_67942533/article/details/126332348

标签:SpringBoot,自动配置
0
投稿

猜你喜欢

  • JDBC使用游标实现分页查询的方法

    2021-06-03 19:07:26
  • Javaweb会话跟踪技术Cookie和Session的具体使用

    2022-06-24 21:16:33
  • 实例解析Json反序列化之ObjectMapper(自定义实现反序列化方法)

    2023-11-23 18:07:25
  • Android自定义RadioGroupX实现多行多列布局

    2023-03-27 17:19:47
  • tk.Mybatis 插入数据获取Id问题

    2023-07-01 22:03:13
  • Android实现花瓣飘落效果的步骤

    2021-11-23 17:16:44
  • Java运算符的知识点与代码汇总

    2022-12-05 19:03:36
  • Unity实现颜色渐变滑动条

    2023-11-28 10:54:51
  • C#微信开发第一章

    2022-02-14 19:16:31
  • 解读@RequestBody与post请求的关系

    2022-10-07 02:02:51
  • Android 短信转换成彩信的消息数量(实例代码)

    2021-11-13 13:01:58
  • C#Process的OutputDataReceived事件不触发问题及解决

    2023-08-12 19:22:41
  • C#反射应用实例

    2023-11-03 14:47:46
  • Spring Boot中如何使用Convert接口实现类型转换器

    2023-05-09 20:28:37
  • Java微信公众号开发之通过微信公众号获取用户信息

    2021-12-16 08:19:19
  • 实例分析java对象中浅克隆和深克隆

    2023-01-07 07:48:20
  • SVN报错:Error Updating changes:svn:E155037的解决方案

    2023-06-11 07:27:11
  • Java 队列实现原理及简单实现代码

    2021-07-19 05:12:56
  • 线程阻塞唤醒工具 LockSupport使用详解

    2023-11-29 17:16:10
  • maven多个plugin相同phase的执行顺序

    2021-07-07 10:33:34
  • asp之家 软件编程 m.aspxhome.com