SpringBoot自动装配原理

步骤

1.main方法加载主配置类

SpringBoot开启,加载主配置类,开启自动配置功能(SpringBootApplication注解下的**EnableAutoConfiguration**注解)

2.组件添入容器过程

利用@EnableAutoConfiguration注解中的@Import({AutoConfigurationImportSelector.class}),给容器导入组件。在AutoConfigurationImportSelector.class中有一个selectImports方法,在这里面调用了getAutoConfigurationEntry方法,在getAutoConfigurationEntry方法中调用getCandidateConfigurations方法,获取候选的配置,而获取的配置是通过调用SpringFactoriesLoader中的loadFactoryNames方法中的返回值(List)loadSpringFactories中的classLoader.getResources方法,扫描下面代码中的内容,

Enumeration<URL> urls = classLoader != null
 ? classLoader.getResources("META-INF/spring.factories") 
 : ClassLoader.getSystemResources("META-INF/spring.factories");

然后把扫描到的内容遍历出来然后一顿操作后包装成Properties对象,然后在Properties对象中获取值,最后把值存到返回结果的Map中,这个结果就是要交给容器中的所有组件,而loadFactoryNames方法的参数,getSpringFactoriesLoaderFactoryClass方法,刚好返回的就是EnableAutoConfiguration.class,所以就相当于从properties对象中获取到EnableAutoConfiguration(类名)对应的值,然后把它们添加到容器中。作用总结就是将类路径下META-INF/spring.factories中所有配置在EnableAutoConfiguration中的类,添加进容器中。
添加进容器的组件
如上图箭头所示,每一个这样的xxxAutoConfiguration都会被配置进容器中,然后由这些容器完成自动配置。

举例:以HttpEncodingAutoConfiguration为例
//Configuration注解表示这是一个配置类
@Configuration(
    proxyBeanMethods = false
)
//启动指定类ServerProperties.class的ConfigurationProperties功能,将配置文件中对应的值与ServerProperties绑定起来,
//并把ServerProperties加入容器中。
@EnableConfigurationProperties({ServerProperties.class})
//Conditional类注解为条件判断注解,满足条件才生效。这里表示判断当前应用是否为Web应用,如果是,当前配置类生效。
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
//判断当前项目有没有CharacterEncodingFilter.class(SpringMVC中用于解决乱码的过滤器)这个类
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断配置文件中是否存在某个配置,即server.servlet.encoding.enabled属性,但由于matchIfMissing 的值为true,表示即使没有配置,也能生效。
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
	private final Encoding properties;
	//默认只有一个有参构造器的情况下,参数的值会去容器中拿到,而参数对象已经在注解中就被加入容器了。
    public HttpEncodingAutoConfiguration(ServerProperties properties) {
        this.properties = properties.getServlet().getEncoding();
    }
    
	@Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
        return filter;
    }

小结:根据当前应用的条件判断,决定这个自动配置类是否生效,若生效,那么这个配置类就会添加大量的组件进容器,而这些组件的属性都是从对应的properties类中获取的,这些类的每一个属性又都是和配置文件绑定的。

总结:

  1. springboot启动会加载大量的自动配置类
  2. 查看我们需要实现的功能有没有springboot已经写好的自动配置类
  3. 查看自动配置类中配置了哪些组件,如果包含我们要用的所有组件,则我们不用再配置
  4. 自动配置类给容器添加组件时,组件的属性是通过properties类获取的,而我们可以通过配置文件来更改properties类的属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值