Spring基础篇:Spring的自定义“模块装配”的步骤

简介: Spring的自定义“模块装配”的步骤

使用场景

主要是 将很多Bean组合起来,就像形成了一个模块,原先使用@Bean@Component<bean>的方式向Spring容器注入bean,所有的bean之间没有明显的关联。如果说遇到某一个场景:我需要依赖大量的bean,有没有一种方式使用一个注解就将所需要的所有bean都导入呢?这就是:模块装配

模块装配的优点在于: 可以将执行特定功能的bean打包成一个整体,哪里需要时,使用一个注解即可将这个整体注入。

例子:我们定义四个动物类,并且尝试使用“模块装配”的方式实现:使用一个注解装四个bean

实现自定模块装配的步骤

定义一个注解

定义注解的意思就是说,我们是通过这个注解来做模块装配的。

定义一个EnableAnimal注解,以Enable起名是有讲究的,因为看到很多以Enable开头的注解就是使用了模块装配这个技术。

  • @Documented:注解(@EnableAnimal)被@Documented标注了,那么被@EnableAnimal修饰的类,生成doc文档时,会在文档个中显示@EnableAnimal
  • @Retention:所注解的注解保留多久,这里的RetentionPolicy.RUNTIME是保留至运行时。
  • @Target:表示该注解只能修饰在哪里,这里表示只能用在类上。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EnableAnimal {
}

关键

除了自定义注解外 ,另外一个最重要的关键就是:@Import注解。这个注解的作用就是:要将哪些bean整合起来(打包)。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import()
public @interface EnableAnimal {
}

现在我们把目光聚焦在@Import()的括号里,也就是它有哪些方式来打包bean

方式一:直接导入类

最简单粗暴的方式,直接在括号里加入需要装配的类名.class,比如说装配Dog.class

@Import(Dog.class)
public @interface EnableAnimal {
}

方式二:导入一个配置类

这个方式其实和方式一的感觉是一样的,只是我们需要先定义一个配置类,然后将这个配置类放在括号中(和方式一一样)。

  • 定义一个配置类,在配置类中注册Pig
@Configuration
public class AssemblyConfig {
    @Bean
    public Pig pig(){
        return new Pig();
    }
}
  • 将配置类写在@Import()
@Import({Dog.class, AssemblyConfig.class})

方式三:实现ImportSelector接口

重写selectImports方法,返回需要导入类的全限定类名。这里我们再注入Cat

public class ImportSelectorImpl implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{Cat.class.getName()};
    }
}

放到注解中的@Import

@Import({Dog.class, AssemblyConfig.class, ImportSelectorImpl.class})

方法四:实现ImportBeanDefinitionRegistrar接口

重写registerBeanDefinitions方法;它导入的是BeanDefinition(这个内容高级篇见)

public class ImportBeanDefinitionRegistrarImpl implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("tuzi",new RootBeanDefinition(Rabbit.class));
    }
}

放到注解中的@Import

@Import({Dog.class, AssemblyConfig.class, ImportSelectorImpl.class,ImportBeanDefinitionRegistrarImpl.class})

测试

OK,我们已经操作四种方式实现模块装配了,现在测试一下IOC容器中都有什么

配置类中导入注解

导入@EnableAnimal自定义注解即可,然后看IOC容器中是否有这四个动物了。

@Configuration
@EnableAnimal
public class AssemblyApplicationConfig {
}

主程序

打印所有在IOC容器中bean的id

public class AssemblyApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AssemblyApplicationConfig.class);
        for (String beanDefinitionName : ctx.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}
目录
相关文章
|
Java 应用服务中间件 Shell
Springboot如何打包部署项目
Springboot如何打包部署项目
1383 0
|
10月前
|
设计模式 算法 Java
我们来说一说什么是 AQS ?
我是小假 期待与你的下一次相遇 ~
772 1
|
关系型数据库 MySQL Java
SpringBoor连接mysql数据库取数据库中时间格式是12小时制的时间,如何显示成24小时制
SpringBoor连接mysql数据库取数据库中时间格式是12小时制的时间,如何显示成24小时制
332 0
|
Java
springboot3 解决:Could not autowire. No beans of ‘JavaMailSender‘ type found
因为 spring-boot-starter-mail 默认使用某些包发生了变化,在 2.2.xx 版本前后不一,解决对应bug
1254 0
|
Java API Spring
Spring Boot中如何实现邮件发送功能
Spring Boot中如何实现邮件发送功能
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
1722 8
|
前端开发 Java 程序员
如何在swagger2中配置header请求头等参数信息?(若不会,我便手把手教你)
如何在swagger2中配置header请求头等参数信息?(若不会,我便手把手教你)
4242 1
|
消息中间件 Java Maven
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
|
运维 前端开发 JavaScript
前端开发新纪元:2024年必知的五大技术趋势
【10月更文挑战第3天】前端开发新纪元:2024年必知的五大技术趋势
1523 0
|
8月前
|
缓存 API 开发者
爱回收批量价格查询 API 接口实战:批量估价上限、请求拆分与效率优化
爱回收批量价格查询 API(接口路径:/v1/device/batch/estimate)是为多设备集中估价场景设计的高效接口,支持一次性传入多个设备的配置信息,批量返回回收报价。其核心优势在于 “减少接口调用次数、提升批量处理效率”,适用于: