Spring Boot 自动装配的原理

Spring Boot自动装配

  • 1. 自动装配的原理
    • 1.1自动装配的实现
      • 1.1.1@EnableAutoConfiguration
      • 1.1.2 AutoConfigurationImportSelector
    • 1.2自动装配原理分析

1. 自动装配的原理

自动装配字面意思理解就是将Bean自动装配到IOC容器中,自动装配是Spring Boot的核心功能。我们可以通过Spring Boot整合redis的例子了解自动装配。

  • 引入依赖:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
  • 在application.properties中配置redis的数据源参数:
spring.redis.host = 127.0.0.1
spring.redis.port = 6379
  • 在HelloServer中使用RedisTemplate实现对redis的操作:
@Service
public class HelloServer {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    public String hello(){
        String hello = redisTemplate.opsForValue().get("hello");
        return hello;
    }
}

上面的例子,我们可以看出,我们并没有通过XML或注解的形式将RedisTemplate注入IOC容器中,却可以在HelloServer中用@Autowired注入RedisTemplate的实例,这说明容器中已经有了RedisTemplate实例,我们只是在配置文件中配置了host和port,这就是自动装配,也是Spring Boot的核心细想:约定大于配置

1.1自动装配的实现

1.1.1@EnableAutoConfiguration

自动装配在Spring Boot中是通过@EnableAutoConfiguration注解开启的,这个注解的声明在启动类注解SpringBootApplocation内。

Spring Boot 自动装配的原理_第1张图片
进入SpringBootApplocation,可以看到@EnableAutoConfiguration的注解声明。
Spring Boot 自动装配的原理_第2张图片
进入@EnableAutoConfiguration,可以看到@Import、AutoConfigurationPackage(使用该注解的类所在的包和子包下所有组件扫描到IOC容器中)的注解声明。
@Import导入了一个AutoConfigurationImportSelector类,我们会根据他的名字猜想一下,应该和自动注入有关,我们接着往下看。
Spring Boot 自动装配的原理_第3张图片

1.1.2 AutoConfigurationImportSelector

AutoConfigurationImportSelector 实现了ImportSelector,ImportSelector有一个返回字符串数组的方法,我们大胆猜想一下,这个数组是不是就是要注入容器的类的名称呢?
Spring Boot 自动装配的原理_第4张图片
我们可以通过一个简单的例子了解一下ImportSelector。

  • 创建两个类,我们要把把他们注入容器。
/**
 * @className: com.xd.learn.basic.boot-> TestOne
 * @description:
 * @author: lxd
 * @createDate: 2022-03-05 11:10 下午
 * @version: 1.0
 */
public class TestOne {
}
/**
 * @className: com.xd.learn.basic.boot-> TestTwo
 * @description:
 * @author: lxd
 * @createDate: 2022-03-05 11:10 下午
 * @version: 1.0
 */
public class TestTwo {
}

  • 自定义一个ImportSelector的实现类XdImportSelector。
/**
 * @className: com.xd.learn.basic.boot-> XdImportSelector
 * @description:
 * @author: lxd
 * @createDate: 2022-03-05 11:11 下午
 * @version: 1.0
 */
public class XdImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{TestOne.class.getName(),TestTwo.class.getName()};
    }
}
  • 自定义一个注解@EnableAutoImport,通过Import导入自定义实现类XdImportSelector。
/**
 * @className: com.xd.learn.basic.boot-> EnableAutoImport
 * @description:
 * @author: lxd
 * @createDate: 2022-03-05 11:12 下午
 * @version: 1.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(XdImportSelector.class)
public @interface EnableAutoImport {
}
  • 创建一个启动类,在启动类上使用@EnableAutoImport注解,即可通过run.getBean从容器中获取到对象。
@SpringBootApplication
@EnableAutoImport
public class EsApplication {
    public static void main(String[] args) {

        ConfigurableApplicationContext run = SpringApplication.run(EsApplication.class, args);
        TestOne testOne = (TestOne)run.getBean("TestOne");
    }
}

1.2自动装配原理分析

通过上面的例子,我们定位到了问题的关键AutoConfigurationImportSelector的实现方法selectImport,它主要有两个功能

  • AutoConfigurationMetadataLoader.loadMetadata(classLoader)从META-INF中记载满族条件的元数据;
  • autoConfigurationEntry.getConfigurations(),搜集所有符合条件的配置类完成自动装配

Spring Boot 自动装配的原理_第5张图片
至此,自动装配的原理基本上及分析完了,简单总结一下核心流程

  • 通过@Import(AutoConfigurationImportSelector)实现配置类的导入;
  • AutoConfigurationImportSelector实现了ImportSelector的接口,用于实现选择性批量配置类的装配;
  • 通过Spring提供的SpringFactoriesLoader机制,扫描classpath路径下的META-INF/spring.factories,读取需要实现的的自动配置类;
  • 通过条件筛选的方式,把不符合条件的配置类移除,最终完成自动状态

你可能感兴趣的:(spring,spring,boot,java)