什么是自动装配

726 阅读3分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

为什么会有自动装配的概念

Spring 英文翻译为春天。

在一段时间内,Spring 确实给 Java 开发人员带来了春天。

然而随着项目的规模不断扩大,Spring 需要配置的地方就越来越多,夸张点说,“配置两小时,Coding 五分钟”。

随着微服务的概念逐渐流行,以及各种语言的简易,对比 Spring 的臃肿,催生出了 Spring Boot。

Spring Boot 简化了文件配置,并且可以直接启动。Spring Boot 实现上述功能主要是基于两种设计策略:开箱即用 和 约定大于配置

开行即用 即是新建一个 Spring Boot 项目时候,只需要给项目路起个名字,然后选好我们需要的组件,就可以直接获得一个可以跑起来的 Spring Boot 项目。

约定大于配置 即是 Spring Boot 已经设置了许多默认参数,Spring Boot 默认你是需要这些的(比如 Spring MVC,而不是 Struts)。

既然 Spring Boot 已经默认设置了一些参数了,那么就需要将这些默认参数加载进去,于是就有了自动装配的概念了。

如何实现 Spring Boot 的自动装配

我们可以通过逐步分析代码来理解什么是自动装配。

查看启动文件

首先进入启动文件,Spring Boot 的启动很简单,执行 StorageApplication 类中的 run 方法即可。类上面有 @SpringBootApplication 注解,该注解标注在哪个类上说明这个类是 Spring Boot 的主配置类,Spring Boot就会运行这个类的 main 方法来启动 Spring Boot 项目。那么 @SpringBootApplication 注解到底是什么呢,我们可以看一下。

@SpringBootApplication
public class StorageApplication {

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

}

查看 @SpringBootApplication 注解

点击进去,我们发现该注解如下:

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

@SpringBootApplication 是一个组合注解。我们一个注解一个注解查看。

查看 @SpringBootConfiguration 注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

点击 @SpringBootConfiguration 注解进去查看,发现这个注解其实就是一个配置类,有 Configuration 注解。

再点击 @Configuration 注解进去查看,

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}

发现该注解有 @Component 注解,这说明 Spring 的配置类也是 Spring 的一个组件。

查看 @EnableAutoConfiguration 注解

@EnableAutoConfiguration 注解其实就是开启自动装配的功能。

点进去查看一下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

查看 @AutoConfigurationPackage 注解

我们先看一下 @AutoConfigurationPackage 这个注解是做什么的。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

这个注解是自动配置包,主要是使用了 @Import 来给 Spring 容器导入了一个组件,这个导入的组件是 Registrar.class

查看 Registrar.class

Spring Boot 项目的启动注解是:@SpringBootApplication,其实它就是由下面三个注解组成的:

@Configuration

@ComponentScan

@EnableAutoConfiguration

其中 @EnableAutoConfiguration 是实现自动配置的入口,该注解又通过 @Import 注解导入了AutoConfigurationImportSelector,在该类中加载 META-INF/spring.factories 的配置信息。然后筛选出以 EnableAutoConfiguration 为 key 的数据,加载到 IOC 容器中,实现自动配置功能!

参考文档