spring中@Import多种作用解析

2,115 阅读1分钟

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:gudepeng.github.io/note/2020/0…

一.作用

1.实例化一个 bean
2.导入一个 configuration
3.导入 ImportSelector 的实现
4.导入 ImportBeanDefinitionRegistrar 的实现

二.案例

@Configuration
@Demo(value="demo",title="demotitle")
@Import({Demo1Bean.class, Demo2Bean.class, DemoImportSelector.class,DemoImportBeanDefinitionRegistrar.class})
public class ImportConfig {
}

1.实例化一个 bean

public class Demo1Bean {
}

直接把这个类实例化成一个 bean

2.导入一个 configuration

@Configuration
public class Demo2Bean {
    @Bean
    public Bean1 bean1(){
       return new Bean1();
    }
}

导入一个配置类

3.导入 ImportSelector 的实现

public class DemoImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
      //获取到该注解的配置值
      Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(Demo.class.getName(), true);
      return new String[]{"com.springimport.demo.selectorbean.Bean2"};
    }
}

根据 return 的类路径实例化 bean

4.导入 ImportBeanDefinitionRegistrar 的实现

public class DemoImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder Bean4 = BeanDefinitionBuilder.rootBeanDefinition(Bean4.class);
        registry.registerBeanDefinition("bean4",Bean4.getBeanDefinition());
        DemoClassPathBeanDefinitionScanner definitionScanner = new DemoClassPathBeanDefinitionScanner(registry, DemoBean.class);
        definitionScanner.registerTypeFilter();
        int beanCount = definitionScanner.scan("com.springimport.demo");
    }
}

获取到 BeanDefinition,通过 registry.registerBeanDefinitio 注册 bean

public class DemoClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
    private Class type;
    public DemoClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, Class<? extends Annotation> type){
        super(registry,false);
        this.type = type;
    }

    public void registerTypeFilter(){
        addIncludeFilter(new AnnotationTypeFilter(type));
    }
}

还有一种比较常见的,通过继承 ClassPathBeanDefinitionScanner 类。去扫描特定路径下的特定注解。这个也是 mybatis 如何使用@Mapper 直接注册成 bean 的方法

DemoClassPathBeanDefinitionScanner definitionScanner = new DemoClassPathBeanDefinitionScanner(registry, DemoBean.class);
definitionScanner.registerTypeFilter();
int beanCount = definitionScanner.scan("com.springimport.demo");

本文样例代码:github.com/gudepeng/de…