Springboot的自动装配原理解析
该注解的作用是用来标识一个springboot应用程序的主启动类的,它也是springboot程序的启动入口。从源代码中可以发现,该注解内部也是有好多个注解加以标注的,包含:
@Target:表示该注解可以作用在哪里(如ElementType.TYPE表示该注解可以作用在类、接口、注解、枚举上)
@Retention:表示定义了Annotation保留的时间长短,换句话说就是被@Retention标注的注解的生存周期,其中主要有三种保留方针(.class / .source / .runtime)
@Documented:这个注解只是用来标注生成javadoc的时候是否会被记录
@Inherited:表示被 @Inherited 注解修饰的注解,如果作用于某个类上,其子类是可以继承的该注解的
@SpringBootConfiguration:表示一个配置类,其本质也是spring中的一个component,在启动类注解中标注也表达了通过该注解来加载IOC容器的配置,因为本质上springboot就是一个spring项目
@EnableAutoConfiguration:表示开启自动装配,它是starter的基础,也是springboot的核心。该注解是springboot进行自动装配的一个核心注解,就是它在背后默默的帮我们进行各种配置。
@ComponentScan:相当于xml配置文件中的<context:component-scan>, 它的主要作用就是扫描指定路径下的标识了需要装配的类,自动装配到spring的Ioc容器中。标识需要装配的类的形式主要是:@Component、@Repository、@Service、@Controller这类的注解标识的类。
但是,在我们对springboot自动装配原理的分析过程中,我们关注更多的是最后三个注解,特别是@EnableAutoConfiguration。
在springboot的自动装配中最重要的一个注解就是@EnableAutoConfiguration注解,它就是执行自动装配的主力军。我们单从名字就可以知道,它的意思是开启自动配置,故见名知意。
根据我的理解它的简单流程是,首先利用其内部的注解@AutoConfigurationPackage内的@Import注解将Registrar.class的Class对象导入,在Registrar内主要做的一个事就是调用registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry),将主启动类所在包及其子包内的的所有组件扫描到spring容器,同时这个设置也解释了为什么程序所创建的controller / service / dao / entity等包一定要与主启动类位于同一个包内,不然程序会报错的原因。
其次,通过进入注解@EnableAutoConfiguration内,会发现有一个导入注解@Import( {AutoConfigurationImportSelector.class} ),它的作用就是导入AutoConfigurationImportSelector的Class对象,并利用该类内部的一个获取配置导入过滤方法getAutoConfigurationImportFilters()来根据pom文件中加入的starter等依赖来将一些需要的配置类灌入到spring容器(applicationContext)中。那么如何去找到相应的配置类呢,也就是一些XXXAutoConfiguration呢?其主要是进入到一个名为Maven: org.springframework.boot:spring-boot-autoconfigure的jar包内的spring-boot-autoconfigure的jar包下的META-INF/spring.factories内利用Spring框架提供的SpringFactoriesLoader这个特性去扫描对应的配置,如此便完成了springboot的装配功能。
王福强说:“魔法”大体上是这样发生的: SpringBoot一旦发现@EnableAutoConfiguration, 那么就使用Spring框架提供的SpringFactoriesLoader这个特性去扫描当前应用classpath下所有
META-INF/spring.factories元信息配置, 然后根据当前使用场景需要(如spring-boot-starter-web), 加载符合当前场景需要的配置类型并供当前或者后继流程使用, 对于@EnableAutoConfiguration的场景,就是提取以org.springframework.boot.autoconfigure.EnableAutoConfiguration作为key标志的一系列Java配置类,然后将这些Java配置类中的bean定义加载或者说灌入Spring容器中。当然, EnableAutoConfiguration通过SpringFactoriesLoader筛选并加载进来的这些Java配置类里面,我们其实还可以进一步对要加载到容器的bean定义进行筛选, 这就会用Spring3系列引入的@Conditional“军团”, 通过像@ConditionalOnClass, @ConditionalOnMissingBean等具体的类型和条件来进一步决定加载还是不加载哪些bean定义。
以上是对于springboot如何进行自动装配的一个分析,如果我们在面试中该如何去给面试官描述呢,其实不必这么细致。
在面试中,我们可以这样说:
Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

浙公网安备 33010602011771号