SpringBoot自动装配原理

发布于:2024-12-07 ⋅ 阅读:(143) ⋅ 点赞:(0)

SpringBoot自动装配原理

在介绍SpringBoot自动装配原理之前我们需要先看一个注解 --> SpringBootApplication

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

我们都知道SpringBootApplication是用来声明引导类的 , 除此之外他还应用于自动装配

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

打开源码我们可以看到 , 除了元注解之外在SpringBootApplication中还提供了三种注解

  • SpringBootConfigurtion --> 声明配置类
  • EnableAutoConfiguration --> 自动装配
  • ComponentScan --> 扫描包

那么SpringBoot自动装配就和EnableAutoConfiguration 该注解相关

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

在这里有两个很重要的注解

  • @AutoConfigurationPackage
  • @Import({AutoConfigurationImportSelector.class})

对于AutoConfigurationPackage它的作用是扫描我们在项目中自行定义的Bean(如Controller , Service , Dao层的Bean) , 其内部通过了Import导入了AutoConfigurationPackages.Registrar.class , 可以扫描项目当中的Bean

而@Import({AutoConfigurationImportSelector.class}) , 就是导入自动配置的选择器 , 该选择器会加载一个文件 , 该文件定义了很多自动配置的类

在这里插入图片描述

这里以RedisAutoConfiguration为列 , 我们看看都做了什么

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

首先我们来看一个注解 @ConditionalOnClass({RedisOperations.class})

该注解是用来判断类路径当中是否包含该字节码文件 , 简单来说就是有没有导入对应的依赖 , 如果导入了才能创建该Bean

除此之外在创建Bean的过程中还会通过

@ConditionalOnMissingBean(
name = {“redisTemplate”}
)

来判断在Bean中是否已经存在过了名为redisTemplate的注解 , 以便于开发者自行配置

==========================================================

面试官:Springboot自动配置原理

候选人

嗯,好的,它是这样的。

在Spring Boot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是实现自动化配置的核心注解。

该注解通过@Import注解导入对应的配置选择器。关键的是内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。

在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。

一般条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。


网站公告

今日签到

点亮在社区的每一天
去签到