走向自动装配|第四章-Spring Boot 自动装配

走向自动装配|第四章-Spring Boot 自动装配

文章说明

Spring Framework 到 Spring Boot 怎么一步一步走向自动装配

项目环境

1.Spring Boot 自动装配

  • 定义:基于规约大于配置原则,实现 Spring 组件自动装配的目的
  • 装配:模式注解、@Enable 模块、条件装配、工厂加载机制
  • 实现:激活自动装配、实现自动装配、配置自动装配实现

2.实现方法

实现的方法分为三步:

1.激活自动装配 - @EnableAutoConfiguration

2.实现自动装配 - XXXAutoConfiguration

3.配置自动装载实现 - META-INF/spring.factories

2.1 Enable 模块

@EnableHelloWorld -> @Import -> HelloWorldConfiguration -> helloWorld

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorld {
}

HelloWorldConfiguration 自动装配的类

public class HelloWorldConfiguration {

    @Bean
    public String helloWorld(){
        return "hello world";
    }
}

2.2 实现自动装配

  • 模式注解装配
  • Enable 模块装配
  • 条件装配
/**
 *  HelloWorld 自动装配
 */
@Configuration // 模式注解装配
@EnableHelloWorld // Enable 模块装配
@ConditionalOnSystemProperty(name = "usr.name", value = "xwf") // 条件装配
public class HelloWorldAutoConfiguration {
}

2.3 配置自动装载

resources/META-INF 目录下新建 spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.huajie.deepinspringboot.configuration.HelloWorldAutoConfiguration

2.4 激活自动装配

@EnableAutoConfiguration
@ComponentScan(basePackages = "com.huajie.deepinspringboot")
public class EnableAutoConfigurationBootstrap {

    static {
        System.setProperty("usr.name","xwf");
    }

    public static void main(String[] args) {

        ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
                .web(WebApplicationType.NONE)
                .run(args);

        String bean = context.getBean("helloWorld", String.class);
        System.out.println("自动装配 hello,world bean : " + bean);
        context.close();
    }
    
}

执行结果:

自动装配 hello,world bean : hello world

如果设置 System.setProperty("usr.name","xwf1"); 为其他信息,则装配失败,因为不符合条件

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'helloWorld' available
...

3.工厂加载机制

Spring 工厂加载机制

  • 实现类:org.springframework.core.io.support.SpringFactoriesLoader
  • 配置资源:resources/META-INF/spring.factories

3.1 装载配置核心方法

  • 根据 factoryClass 类型来查找,spring.factories 中配置的相关实现类
  • 通过 instantiateFactory 实例化这个类,存放到 ArrayList 集合,并返回
	public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {
		Assert.notNull(factoryClass, "'factoryClass' must not be null");
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
		if (logger.isTraceEnabled()) {
			logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
		}
		List<T> result = new ArrayList<>(factoryNames.size());
		for (String factoryName : factoryNames) {
			result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
		}
		AnnotationAwareOrderComparator.sort(result);
		return result;
	}

3.2 调用链路

org.springframework.boot.SpringApplication#run(java.lang.String…)

  • org.springframework.boot.SpringApplication#refreshContext
    • 在启动应用上下文的过程中(这个里面涉及到 Spring Framework 启动的生命周期,过程较多省略)
    • org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process
      • org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports
        • org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations
          • org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories

3.3 调试截图

getCandidateConfigurations 中获取到 spring.factories 配置的 EnableAutoConfiguration 的所有实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ychfIOLX-1590390007507)(G:\workspace\csdn\learn-document\spring-boot\慕课课程\csdn\image-20200525143026525.png)]
我们只需要将对应的自动装配类配置在默认的 resources/META-INF/spring.factories 中就可以了,通过这种工厂加载机制会自动获取。

4.系列总结

通过本系列这四篇章,我们可以知道,其实 Spring Boot 的自动装配特性,大部分的技术都是源自 Spring Framework,比如模式注解 @Configuration,@Enable 模块驱动,条件装配等等;Spring Boot 结合 Spring 工厂加载机制进一步将这些技术做了有机的整合,达到自动装配的效果。

在大多数场景,我们看不到 @EnableAutoConfiguration 注解的原因是,@SpringBootApplication 注解中包含了 @EnableAutoConfiguration 注解。

5.参考

  • 慕课网-小马哥《Spring Boot2.0深度实践之核心技术篇》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值