Spring中使用@Import注册一个配置类时,这个配置类不应该再使用@Component或者@Configuration注解

@Import注解参数三种类型

普通Bean类型

被导入的类会被注册成Spring容器中的一个Bean,可以被依赖注入使用,beanName为全类名。

ImportSelector类型

ImportSelector实现类不会被注册为Spring容器的一个Bean,但是其接口方法返回的全类名会被注册成bean,并且beanName为全类名

//MyImportSelector不会被注册为bean
public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //ImportedBean1被注册为bean,并且beanName为全类名
        return new String[]{ImportedBean1.class.getName()};
    }
}

ImportBeanDefinitionRegistrar类型

ImportBeanDefinitionRegistrar实现类不会被注册为bean,但是会回调其接口方法,由开发者通过Spring api手动向Spring容器注册bean

public MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){
	   //可以通过registry向Spring容器注册bean
	}
}

@Import注册一个配置类时,这个配置类不应该被@Component或者@Configuration注解标记。

Spring中会将所有的bean class封装成一个ConfigurationClass,并且此后会解析这些配置类,该类中会有一个boolean类型返回值方法boolean ConfigurationClass#isImported,用于判断被封装的bean class是否是由其他类导入的。方法注释如下:

Return whether this configuration class was registered via @Import 
or automatically registered due to being nested within another configuration class.

中文解释:如果是通过@Import注册的类或者在配置类中定义的内部类会返回true,这里理解是否由其他类导入的。
如下示例:

//其他代码省略....
@Import(B.class)
@ConditionOnBean(C.class) //条件验证bean C是否存在
class A{
   //只有当A上的条件验证通过时才会向Spring容器注入D
   @Bean
   public D d(){
       return new D();
   }
}

示例中B就是由A导入的一个Bean

当被导入的类B在被实例化时,Spring会先验证导入B的A类上的条件注解是否验证通过,如果通过才会实例化B。而条件验证注解的结果同时会被缓存。

@Component或者@Configuration注解会让被@Import导入的类B,在Spring执行包扫描时被扫描到,此时不会被认为是由类A导入的。假如此时实例化Bean B,但是B依赖了A中定义的bean D,但是A此时的条件验证是不通过的,则会导致bean B创建时无法依赖bean D,最后抛出异常。

如果类B正常由类A导入,没有被@Component或者@Configuration注解,那么在bean B实例化之前,会先验证类A上的条件注解是否通过,如果通过,那么类B在实例化过程中所依赖A中定义的bean D时也能够正常被创建,并被B所有依赖注入。如果不通过,则不会创建bean B,此时也不会查找从Spring容器中查找A中所定义的bean D,应用正常执行.

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
@Import注解Spring框架一个注解,它用于将其他配置导入到当前。@Import可以单独使用,也可以和其他注解一起使用,例如@Configuration注解ImportSelector接口和ImportBeanDefinitionRegistrar接口。 当@Import注解单独使用时,它可以直接将其他普通的导入到当前,以便在当前可以使用导入。 当@Import注解结合@Configuration注解ImportSelector接口和ImportBeanDefinitionRegistrar接口使用时,在Spring Boot是最常见的用法之一。举个例子,如果我们在一个使用@EnableAutoConfiguration注解,那么在该注解的源码使用@Import注解导入AutoConfigurationImportSelector。这样,通过@EnableAutoConfiguration注解,我们可以自动配置应用程序的一些默认设置。 总结来说,@Import注解是用来将其他配置导入到当前注解,可以单独使用,也可以和其他注解一起使用,常见的用法是结合@Configuration注解ImportSelector接口和ImportBeanDefinitionRegistrar接口在Spring Boot实现自动配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [@Import注解的四种使用方式](https://blog.csdn.net/bluemysky/article/details/128827769)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [@Import注解使用](https://blog.csdn.net/m0_55806905/article/details/127967036)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值