模块装配是 SpringBoot 中自动装配的基础,等后面我们整理 SpringBoot 相关的文章的时候,就会有明显的体现。

1. 什么是模块装配

1.1 什么是模块

模块的字面概念,我们可以理解为具有独立功能的高内聚模块。多个模块之间可以相互依赖,例如用户模块、权限模块,它们整个模块都是在做同样的事情。

1.2 什么是模块装配

简单的说,就是把一个模块需要的核心功能组件都装配好。

2. 一个简单的例子

例如我的一个模块叫做 MyWork,其中具有 PartA 这样的组件,当然可能有多个,我这里只是写了一个例子。然后我们来看看。通过一个 @Import 注解就在其它模块配置 EnableMyModule 注解的时候,就能自动引入 PartA,如果有多个组件 part,配置好,就都可以直接引入(@Import 后面加花括号,通过逗号隔开)。

  1. public class PartA {
  2. }
  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target(ElementType.TYPE)
  4. @Import(PartA.class)
  5. public @interface EnableMyModule {
  6. }
  1. @Configuration
  2. @EnableMyModule
  3. public class MyModuleConfiguration {
  4. }
  1. public class Test {
  2. public static void main(String[] args) {
  3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyModuleConfiguration.class);
  4. Stream.of(context.getBeanDefinitionNames()).forEach(System.out::println);
  5. }
  6. }

3. 模块装配的几种方式

3.1 装配普通类

上述的一个简单例子就是装配普通类

3.2 装配配置类

  1. public class PartA {
  2. private String name;
  3. public PartA(String name) {
  4. this.name = name;
  5. }
  6. }
  1. @Configuration
  2. public class MyModuleConfiguration {
  3. @Bean
  4. public PartA zhangsan() {
  5. return new PartA("张三");
  6. }
  7. @Bean
  8. public PartA lisi() {
  9. return new PartA("李四");
  10. }
  11. }
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({PartA.class, MyModuleConfiguration.class})
public @interface EnableMyModule {

}
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyModuleConfiguration.class);
        Stream.of(context.getBeanDefinitionNames()).forEach(System.out::println);

        System.out.println("------------------");

        Map<String, PartA> map = context.getBeansOfType(PartA.class);
        map.forEach((name, partA) -> System.out.println(partA));

    }
}

运行结果:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myModuleConfiguration
zhangsan
lisi
------------------
com.ideal.enable.PartA@54c562f7
com.ideal.enable.PartA@318ba8c8

3.4 ImportSelector

上面的没变,我们使用一下 ImportSelector

public class MyModuleImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {PartA.class.getName(), MyModuleConfiguration.class.getName()};
    }
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({PartA.class, MyModuleImportSelector.class})
public @interface EnableMyModule {

}

3.4 ImportBeanDefinitionRegistrar

public class MyModuleRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("waiter", new RootBeanDefinition(PartA.class));
    }
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({PartA.class, MyModuleRegistrar.class})
public @interface EnableMyModule {

}