Spring註解之@Import

2022-12-22 18:01:59

 

@Import可以匯入以下幾種種類:
  • 普通類
  • 實現ImportSelector介面的類
  • 實現DeferredImportSelector介面的類
  • 實現ImportBeanDefinitionRegistrar介面的類

 

普通類

被匯入的類會被容器註冊成一個Bean,可以被依賴注入使用。【4.2 版本之前只可以匯入設定類;4.2版本之後也可以匯入普通類,匯入的類會被當作設定類】
 
@Import註冊一個類時,這個設定類不應該被@Component或者@Configuration註解標記。Spring中會將所有的bean class封裝成一個ConfigurationClass,並且此後會判斷被封裝的bean class是否是由其他類匯入的.
@Configuration
@Import(OtherBean.class)
public class SpringConfig { }
public class OtherBean { }

 

ImportSelector實現類

實現類不會被註冊成Bean,介面方法的返回值會被註冊成Bean。【BeanName是全類名】

@Configuration
@Import(MyImportSelector.class)
public class SpringConfig { }
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{OtherBean.class.getName()};
    }
}

 

DeferredImportSelector實現類

DeferredImportSelector是ImportSelector的子介面, 所以它們的實現方式一樣,只是Spring的處理方式不同。DeferredImportSelector和SpringBoot中自動匯入組態檔的延遲匯入有關。
@Configuration
@Import(MyDeferredImportSelector.class)
public class SpringConfig { }
public class MyDeferredImportSelector implements DeferredImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{OtherBean.class.getName()};
    }
}

 

ImportBeanDefinitionRegistrar實現類

實現類不會被註冊為bean,但是會回撥其介面方法,由開發者通過Spring api手動向Spring容器註冊bean。【類似於BeanFactoryPostRegister】

@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringConfig { }
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition = new RootBeanDefinition();
        String beanName = StringUtils.uncapitalize(OtherBean.class.getSimpleName());
        beanDefinition.setBeanClassName(OtherBean.class.getName());
        registry.registerBeanDefinition(beanName,beanDefinition);
    }
}