SpringBoot源碼|深入理解@Import注解
深入理解@Import注解
查看SpringBoot相关组件的源码,会发现有很多地方运用了@Import注解,这个注解有什么用呢,工作原理是什么,我们可以利用这个@Import来做什么?
1 2 3 4 5 6
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { Class<?>[] value(); }
|
@Import的使用方式
1 2 3 4 5 6 7
| public class Client { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); ServiceImpl service = applicationContext.getBean(ServiceImpl.class); Assert.notNull(service,"service has inject successful"); } }
|
Configuration
通过@Import将Class加载到AppConfig类中
1 2 3 4
| @Configuration @Import(value = ServiceImpl.class) public class AppConfig { }
|
ImportBeanDefinitionRegistrar
1 2 3
| public interface ImportBeanDefinitionRegistrar { void registerBeanDefinitions(AnnotationMetadata var1, BeanDefinitionRegistry var2); }
|
自定义BeanDefinitionRegistrar的实现
1 2 3 4 5 6 7 8
| public class ServiceBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{ @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServiceImpl.class); beanDefinitionRegistry.registerBeanDefinition("service",builder.getBeanDefinition()); } }
|
1 2 3 4
| @Configuration @Import(value = ServiceBeanDefinitionRegistrar.class) public class AppConfig { }
|
通过ImportBeanDefinitionRegistrar实现的Import可以针对Bean注册容器的过程进行自定义
ImportSelector
告诉容器需要注入哪些类的类名就可以实现Bean的注入
1 2 3
| public interface ImportSelector { String[] selectImports(AnnotationMetadata var1); }
|
1 2 3 4 5 6 7
| public class ServiceImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{ServiceImpl.class.getName()}; } }
|
1 2 3 4
| @Configuration @Import(value = ServiceImportSelector.class) public class AppConfig { }
|
- 总结
获取注解元数据信息,返回一组需要注入类的类名,有框架来生成对应的实体类从而注入到容器中去。