Spring注解之@Import

时间:2022-12-22 16:06:51

 

@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);
    }
}