热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

SpringBoot实现模块化的几种方法

模块可以是业务模块,为应用程序提供一些业务服务,或者为几个其他模块或整个应用程序提供跨领域关注的技术模块。这篇文章主要介绍了SpringBoot实现模块化,需要的朋友可以参考下

一般情况下,一个SpringBoot应用 = 一个微服务 = 一个模块 = 一个有边界的上下文,如果有多个模块,我们就开发多个微服务,多个SpringBoot应用,然后使用Springcloud实现它们之间动态访问和监控。 但是有时我们也会希望将多个模块放入一个SpringBoot应用中,这样模块之间调用可以在一个JVM内进行,适合小型系统的部署,随着规模扩大,我们还可将这些模块变成一个个微服务,以SpringBoot应用分布式运行。

SpringBoot为模块化提供了非常直接简单的组合方式,可以说完全替代OSGI或其他模块插件技术。

什么是Spring Boot中的模块?

本文意义上的“模块”是一组加载到应用程序上下文中的Spring组件。

模块可以是业务模块,为应用程序提供一些业务服务,或者为几个其他模块或整个应用程序提供跨领域关注的技术模块。

创建模块的几种办法

Spring模块的基础是一个@Configuration注释,这是一种Spring的Java配置特性,可以用来标注在你的模块配置类中,配合@Configuration有几种更细粒度的方式:

(1)@ComponentScan

创建模块的最简单方法是使用@ComponentScan注释:

@Configuration
@ComponentScan(basePackages = "io.reflectoring.booking")
public class BookingModuleConfiguration {
}

如果这个配置类由importing 机制(稍后解释)导入的一个,它将查看包io.reflectoring.booking中的所有类,如果使用了 Spring的构造型注释 中任何一个注释,这些类的实例将被加载到Spring的应用上下文中。

只要你总是希望将包及其子包的所有类加载到Spring应用上下文中,那么使用这种方式就可以了。如果你需要更多控制加载内容,请继续。。

(2)@Bean 定义

Spring的Java配置功能还有一个@Bean注释,用于创建加载bean的实例到Spring应用上下文中:

@Configuration
public class BookingModuleConfiguration {
 @Bean
 public BookingService bookingService(){
  return new BookingService();
 }
 // potentially more @Bean definitions ...
}

导入此配置类时,BookingService实例将被创建并插入Spring的应用上下文中。

使用这种方式进行模块的创建就可以更清楚地了解实际加载的bean,因为你只需要查看一个地方(配置类),更方便 ,这种办法与使用@ComponentScan地方相比,后者需要你查看包中所有类的构造型注释,看看是什么构造型,符合条件才能被加载。

(3)@Conditional 注释

如果你需要对哪些组件应该加载到Spring应用上下文中要进行更细粒度的控制,则可以使用Spring Boot的@Conditional...注释:

@Configuration
@ConditionalOnProperty(name = "io.reflectoring.security.enabled", 
  havingValue = "true", matchIfMissing = true)
public class SecurityModuleConfiguration {
 // @Bean definitions ...
}

在使用这个模块时,必须在application配置文件中设置属性io.reflectoring.security.enabled为true才能使用这个模块。(见后面使用模块)

还可以使用其他@Conditional...注释来定义加载模块的条件。有一个依赖条件,具体取决于JVM的版本以及某个类是否存在于类路径中或某个bean是否存在于Spring应用上下文中。

如果你曾经问​​过自己Spring Boot如何神奇地将应用程序所需的bean加载到应用程序上下文中,原理就在于使用了这个注释@Conditional,Spring Boot本身大量使用@Conditional注释。

以上三种办法是创建一个模块的方式,那么如何使用这些模块呢?也有几种方式可选,注意,要分清模块创建和模块使用两个大的边界。

使用模块的几种办法

创建模块后,我们需要将其导入到SpringBoot应用程序中,有下面几种办法:

(1)@Import

最直接的方法是使用@Import注释:

@SpringBootApplication
@Import(BookingModuleConfiguration.class)
public class ModularApplication {
 // ...
}

这将导入BookingModuleConfiguration类及其随附的所有bean - 无论它们是由声明@ComponentScan还是@Bean注释。

(2)@Enable... 注释

Spring Boot带有一组注释,每个注释都自己导入某个模块。一个例子是@EnableScheduling,它导入调度子系统所需的所有Beans及其@Scheduled注释,也就是说,如果你在你的应用类中使用了@Scheduled注释,如果想使得这种调度功能起效,还必须在入口处加入@EnableScheduling,否则就不起效,这也是SpringBoot使用中容易掉的坑,关键还是没有了解Spring的模块机制:

@SpringBootApplication
@EnableScheduling
public class SpringbatchApplication {

 public static void main(String[] args) {
 SpringApplication.run(SpringbatchApplication.class, args);
 }
}

我们也可以导入自己的Enable配置:

@SpringBootApplication
@EnableBookingModule
public class ModularApplication {
 public static void main(String[] args) {
 SpringApplication.run(ModularApplication.class, args);
 }
}

上面代码中EnableBookingModule不是Spring自己的注释,而是我们自己的定做的,代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import(BookingModuleConfiguration.class)
@Configuration
public @interface EnableBookingModule {
}

该@EnableBookingModule注释实际上只是包装了@Import,首先导入我们的BookingModuleConfiguration,如果我们有一个模块是由多个配置类组成,这种办法是一种将这些配置类聚合到单个模块中的方便且富有表现力的方法。

(3)自动配置Auto-Configuration

如果我们想自动加载模块而不是将之前那样在源代码中导入指定的硬连接hard-wiring,我们可以使用Spring Boot的自动配置功能,也就是不再源代码中使用注释,而是使用配置文件。

请在模块所在项目下(注意,不是模块使用的项目)建立文件META-INF/spring.factories,运行时需要放入classpath类路径中 ,在该文件中写入:

org.springframework.boot.autoconfigure.EnableAutoCOnfiguration=\
 io.reflectoring.security.SecurityModuleConfiguration

多个配置:

org.springframework.boot.autoconfigure.EnableAutoCOnfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

该模块的使用者所在Springboot项目启动时会将SecurityModuleConfiguration类的所有bean导入到Spring应用上下文中。

要在SpringBoot中使用这个SecurityModuleConfiguration,还需要在模块使用的项目中在application.yml中定义:

io:
 reflectoring:
  security:
   enabled: true

这里将io.reflectoring.security.enabled设置true,是对应前面该模块创建时使用@Conditional注释时有一个条件:

@ConditionalOnProperty(name = "io.reflectoring.security.enabled", 
  havingValue = "true", matchIfMissing = true)

使用模块的策略

前面介绍了在Spring Boot应用程序中使用模块的几个办法,但是我们什么时候在什么情况下选择哪一个呢?

(1)业务模块使用@Import

对于包含业务逻辑的模块 - 比如上面的BookingModuleConfiguration - 在大多数情况下使用@Import,使用带注释的静态导入应该足够了。通常那些没有加载业务模块也是没有意义的,因此我们不需要对它们的加载条件进行任何控制。

(2)技术模块使用自动配置

另一方面,技术性的模块 - 如安全SecurityModuleConfiguration - 这些技术通常会提供一些跨域的切面关注(类似AOP),例如日志记录,异常处理,授权或监视功能,这些功能在开发和运行时需求不一样,在开发过程中,可能根本不需要这些功能,因此我们希望有一种方法来禁用它们。

我们不希望使用@Import静态地导入每个技术模块,因为它们不应该对我们的代码产生任何影响。

因此,使用技术模块的最佳选择是自动配置功能。模块在后台静默加载,我们可以使用在代码之外配置属性中影响它们。

本文案例: github

总结

以上所述是小编给大家介绍的Spring Boot实现模块化的几种方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • 云计算的优势与应用场景
    本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
  • 随着网络安全威胁的不断演变,电子邮件系统成为攻击者频繁利用的目标。本文详细探讨了电子邮件系统中的常见漏洞及其潜在风险,并提供了专业的防护建议。 ... [详细]
  • 探讨架构师在项目中应如何平衡对产品的关注和对团队成员的关注,以实现最佳的开发成果。 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • 本文探讨了2012年4月期间,淘宝在技术架构上的关键数据和发展历程。涵盖了从早期PHP到Java的转型,以及在分布式计算、存储和网络流量管理方面的创新。 ... [详细]
  • 2018年3月31日,CSDN、火星财经联合中关村区块链产业联盟等机构举办的2018区块链技术及应用峰会(BTA)核心分会场圆满举行。多位业内顶尖专家深入探讨了区块链的核心技术原理及其在实际业务中的应用。 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • 本文探讨了Java编程的核心要素,特别是其面向对象的特性,并详细介绍了Java虚拟机、类装载器体系结构、Java类文件和Java API等关键技术。这些技术使得Java成为一种功能强大且易于使用的编程语言。 ... [详细]
author-avatar
乐思GO_361
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有