Spring Boot自动装配原理(1)— Spring Cloud Alibaba微服务原理与实战笔记
在Spring Boot中,自动装配是一个不得不提的话题,它是构建一个Starter的基础,也是Spring Boot的核心,那么这个自动主要体现在哪儿呢?
阅读时间预计:10min 😃
自动装配机制
首先要说,装配就是把Bean放在IoC容器中去,举个简单的栗子:
@RestController
public class MyController{
@Autowired
private final MyService mySevice; //包含一个public String hello(){return "hello!";}
@GetMapping("/Hello")
public String Hello(){
rerturn myService.hello();
}
}
在上面的controller中,我们并没有把MyService注入到IoC中,但却可以使用@Autowired注解的方式注入myService实例,这就说明在此之前IoC容器中已经存在了MyService。这就是Spirng Boot的自动装配机制。
自动装配的实现
先看这一段maven依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
我们回想一下,但我们在添加一个Starter以来以后,在代码中就可以直接使用而不需要手动XML或者注解注入相关的组件。如果自动装配对于任何Starter都满足这样的需求,那么Starter必定要实现某种约定或者规范,才可以让Spring Boot能够对组件进行自动装配。
那么,先上最简单的结论:自动装配在Spring Boot中是通过@EnableAutoConfiguration注解开启的,而它是在@SpringBootApplication中的。
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class,args);
}
}
进入@SpringBootApplication注解可以看到@EnableAutoConfiguration注解的声明:
@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 {
//省略
}
其实熟悉Spring3.1以后版本的小伙伴应该知道,@Enable注解是Spring把相关组件装配到IoC容器中的主要方式,而它也是对@Configuration和@Bean的封装,所以大家可以在相关的注解中会发现,这些注解都会携带一个@Import注解,比如@EnableScheduling:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}
那么,在Spring Boot中也使用类似的方法。我们继续进入到@EnableAutoConfiguration中去:
@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 {};
}
到这里,其实聪明的下伙伴已经注意到了@Import({AutoConfigurationImportSelector.class})注解。那么还要说的是@AutoConfigurationPackage注解,它的作用是把使用了该注解的类所在的包及子包下所有组件扫描到Spring IoC容器中。
所以,到这里我们就可发现,@Import注解导入的是一个AutoConfigurationImportSelector类,那么它一定会实现配置类的导入,至于导入的方式和普通的@Configuration有什么区别,就需要我们继续分析。