模块装配是 SpringBoot 中自动装配的基础,等后面我们整理 SpringBoot 相关的文章的时候,就会有明显的体现。
1. 什么是模块装配
1.1 什么是模块
模块的字面概念,我们可以理解为具有独立功能的高内聚模块。多个模块之间可以相互依赖,例如用户模块、权限模块,它们整个模块都是在做同样的事情。
1.2 什么是模块装配
2. 一个简单的例子
例如我的一个模块叫做 MyWork,其中具有 PartA 这样的组件,当然可能有多个,我这里只是写了一个例子。然后我们来看看。通过一个 @Import 注解就在其它模块配置 EnableMyModule 注解的时候,就能自动引入 PartA,如果有多个组件 part,配置好,就都可以直接引入(@Import 后面加花括号,通过逗号隔开)。
public class PartA {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(PartA.class)
public @interface EnableMyModule {
}
@Configuration
@EnableMyModule
public class MyModuleConfiguration {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyModuleConfiguration.class);
Stream.of(context.getBeanDefinitionNames()).forEach(System.out::println);
}
}
3. 模块装配的几种方式
3.1 装配普通类
3.2 装配配置类
public class PartA {
private String name;
public PartA(String name) {
this.name = name;
}
}
@Configuration
public class MyModuleConfiguration {
@Bean
public PartA zhangsan() {
return new PartA("张三");
}
@Bean
public PartA lisi() {
return new PartA("李四");
}
}
@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 {
}