我们今天再来说一下关于 SpringBoot 的自动装配,为什么会有这样的问题呢?一般这种情况都是在面试的过程中,面试官有时候会问到这个问题,就比如从开始问SpringBoot 的一些常用注解,到SpringBoot的一些特性,然后引申到这个 SpringBoot 的自动装配上来。今天就和了不起一起来聊聊关于这个 SpringBoot 的自动装配吧。
什么是SpringBoot的装配
Spring Boot 的自动装配(Auto-Configuration)是指 Spring Boot 会根据项目中添加的依赖和其他因素,自动配置你的 Spring 应用程序。这一特性使得开发者在创建 Spring 应用程序时,可以省去大量的手动配置工作,从而快速启动和运行应用程序。
自动装配流程
SpringBoot的自动装配工作流程主要基于其核心注解和一系列的配置机制,以下是对其工作流程的详细解析:
1.启动注解:
- SpringBoot的自动装配始于@SpringBootApplication注解。这个注解实际上是@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解的组合。
2.@SpringBootConfiguration:
- @SpringBootConfiguration注解本质上是一个@Configuration注解的包装,用于声明当前类是一个配置类,可以定义Bean,也可以引入其他配置类。
3.@EnableAutoConfiguration:
- 这是实现自动装配的关键注解。它包含了@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)两个子注解。
- @AutoConfigurationPackage:用于自动配置包,使得主配置类(带有@SpringBootApplication注解的类)所在的包及其子包中的组件都能被Spring容器扫描到。
- @Import(AutoConfigurationImportSelector.class):这个注解的作用是导入类,但在这里它并不是直接导入一个普通的类,而是导入了一个实现了ImportSelector接口的类AutoConfigurationImportSelector。这个类的作用是根据一定的规则(比如类路径下的META-INF/spring.factories文件)来加载并配置一些自动装配的类。
4.META-INF/spring.factories:
- 在Spring Boot的自动装配过程中,META-INF/spring.factories文件起到了非常关键的作用。这个文件是Spring Boot用来加载自动配置类的一个约定俗成的文件,它位于各个Spring Boot Starter的jar包中。Spring Boot在启动时,会扫描所有jar包中的META-INF/spring.factories文件,并将其中配置的自动配置类加载到Spring容器中。
5.自动配置类:
- 这些类通常是以AutoConfiguration结尾的,它们使用@Configuration注解标注,并且内部定义了一些Bean。这些Bean就是Spring Boot自动装配到Spring容器中的组件。
6.条件装配:
- 在自动配置类中,经常可以看到@ConditionalOnClass、@ConditionalOnProperty等条件注解。这些注解的作用是判断当前环境是否满足某个条件,如果满足则进行自动装配,否则不进行装配。这样可以根据项目的实际情况来灵活地选择需要装配的组件。
7.总结:
SpringBoot的自动装配工作流程大致可以归纳为:首先通过@SpringBootApplication注解启动Spring Boot应用,然后利用@EnableAutoConfiguration注解中的@Import(AutoConfigurationImportSelector.class)来加载META-INF/spring.factories文件中配置的自动配置类,最后根据这些自动配置类中的定义和条件注解来将相应的组件装配到Spring容器中。
自动装配的核心
@SpringBootApplication
这个注解,就是自动装配的核心,我们来详细解读一下这个 @SpringBootApplication
它其实是一个组合注解,用于简化 Spring Boot 应用的配置。这个注解通常被用在 Spring Boot 的主类上,以指示该类是一个特殊的配置类,用于引导应用上下文的启动。
组成部分
1.@SpringBootConfiguration:
- 这是一个特殊的 @Configuration 注解,表示该类是一个配置类,并告诉 Spring Boot 这是一个特殊的配置类,用于加载应用的上下文设置。
- 实际上,@SpringBootConfiguration 仅仅是 @Configuration 的一个特殊版本,并且二者在功能上没有区别。但 @SpringBootConfiguration 更多地用于标识这是一个 Spring Boot 应用。
2.@EnableAutoConfiguration:
- 这是 Spring Boot 的核心特性之一。它告诉 Spring Boot 根据添加的 jar 依赖项、类路径设置、各种属性设置等自动配置你的 Spring 应用。例如,如果你的类路径下有 spring-boot-starter-web,那么 Spring Boot 会自动配置嵌入式 Tomcat 服务器和 Spring MVC。
- 你可以通过 spring.autoconfigure.exclude 属性来排除某些自动配置。
3.@ComponentScan:
- @ComponentScan 告诉 Spring 扫描当前包及其子包下的组件(如 @Component、@Service、@Repository、@Controller 等),并将它们注册为 Spring Bean。
- 默认情况下,它会扫描标注了 @SpringBootApplication 注解的类所在的包及其子包。你可以通过 basePackages 或 basePackageClasses 属性来指定扫描的包。
如果这个时候,我们给面试官解释了这个 SpringBoot的自动装配的原理之后,面试官很大程度上就开始要往下延伸内容了,既然 @Autowired 能实现了则个自动装配,那么还有其他注解么?以及他和 @Autowired 的区别在哪呢?
@Resource和@Autowire
@Resource 和 @Autowired 都是 Spring 框架中用于自动装配 bean 的注解,但它们之间有一些区别。以下是这两个注解的主要区别:
来源不同
@Autowired 是 Spring 特有的注解,用于自动装配 bean。
@Resource 是 Java 的标准注解,属于 JSR-250 规范的一部分,但 Spring 也支持它作为自动装配的注解。
@Autowired
@Autowired 是 Spring 特有的注解,用于自动装配 bean。Spring 容器会检查 bean 的属性、方法以及构造器,然后使用与指定类型相匹配的 bean 进行自动装配。
- 类型匹配:默认情况下,@Autowired 是基于类型(Type)的自动装配。如果存在多个相同类型的 bean,那么就需要使用其他机制(如 @Qualifier 注解或 @Primary 注解)来进一步指定。
- 构造器注入:Spring 4.3 之后,推荐使用构造器注入来替代字段注入,因为它可以提供更好的不可变性和测试性。
- 可配置性:@Autowired 是可选的,并且可以通过 Spring 的配置文件(如 XML 文件)进行更详细的配置。
@Resource
@Resource 是 Java EE 的一部分(来自 JSR-250),同时也是 Spring 支持的注解。它提供了更丰富的功能,包括指定名称(name)和类型(type)来查找 bean。
- 名称和类型匹配:与 @Autowired 相比,@Resource 提供了更灵活的匹配方式。它可以基于名称(如果提供了)或类型进行查找。如果同时指定了名称和类型,并且找不到匹配的 bean,那么就会抛出异常。
- 与 Java EE 兼容:由于 @Resource 是 Java EE 的一部分,因此它可以在任何支持 Java EE 的环境中使用,而不仅仅是 Spring。
到这里,本篇文章就接近尾声了,关于 SpringBoot的自动装配,你掌握了多少呢?