SpringBoot如何加载代码根目录之外的Bean

这片文章中会找到你想要的答案。

*看一个SpringBoot入口类

package com.example.multithread;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MultithreadApplication {

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

}

*耀眼的@SpringBootApplication注解

springboot 加载完成后手动 注入bean springboot加载bean原理_spring boot

*它继承了哪些注解

(加在它之上的注解)

1-首先是四个元注解

@Target(ElementType.TYPE)

标志该注解可以作用于interface、class、enum。

@Retention(RetentionPolicy.RUNTIME)

注解的保留策略;

这里的策略是:
当前注解会出现在.class字节码文件中,
并且在运行的时候可以通过反射被获得。

@Documented

标志该注解可以被javadoc工具所引用。

@Inherited

标志该注解可以被继承。

2-@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

@SpringBootApplication相当于是这三个注解的组合,
我们主要说一下这三个。

*@SpringBootConfiguration

springboot 加载完成后手动 注入bean springboot加载bean原理_根目录_02


可以看到它继承了@Configuration;

Spring3.0开始增加了@Configuration、@Bean注解,

支持通过Java类(JavaConfig)的形式进行更直观的配置。

例如:

@Bean
public HttpMessageConverters fastjsonHttpMessageConverter(){
	//定义消息转换对象
	FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();

	HttpMessageConverter<?> converter = fastConverter;

	return new HttpMessageConverters(converter);
}

*@ComponentScan

@ComponentScan与@Component这一类的注解配合使用,
相当于以前xml配置中开启自动扫描的context:component-scan标签,
可以配置Spring的扫描范围、Bean的ID命名策略等属性;

默认扫描范围为当前目录下的所有class,
这也是SpringBoot入口类要放在代码根目录的原因。

*@EnableAutoConfiguration

需要注意一下这个@Import(AutoConfigurationImportSelector.class)

springboot 加载完成后手动 注入bean springboot加载bean原理_spring_03


@ComponentScan会扫描并装配代码根目录下的,

所有的带@Component注解的class;

但是SpringBoot如何加载代码根目录之外的Bean,

比方说classpath下maven依赖中的;

这个时候就需要了解一下META-INF/spring.factories文件的作用了。

1-META-INF/spring.factories

META-INF/spring.factories存在于某些依赖的jar包中

springboot 加载完成后手动 注入bean springboot加载bean原理_加载_04


它里面有一个属性:EnableAutoConfiguration。

2-EnableAutoConfiguration

springboot 加载完成后手动 注入bean springboot加载bean原理_spring_05


它用来记录jar包中需要注册到容器中的Bean的qualified name,

这样可以通过反射获取到对应的class,

然后前边@Import中的AutoConfigurationImportSelector.class就该工作了。

3-AutoConfigurationImportSelector

它里边有一个方法:

getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes),

作用是加载这些定义在spring.factories中的Bean。

springboot 加载完成后手动 注入bean springboot加载bean原理_根目录_06

不当之处,还请指正!