Spring Boot实现模块化的几种方法

一般情况下,一个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实现模块化的几种方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 浅谈springboot多模块(modules)开发

    为何模块开发 先举个栗子,同一张数据表,可能要在多个项目中或功能中使用,所以就有可能在每个模块都要搞一个mybatis去配置.如果一开始规定说这张表一定不可以改字段属性,那么没毛病.但是事实上, 一张表从项目开始到结束,不知道被改了多少遍,所以,你有可能在多个项目中去改mybatis改到吐血! 在举一个栗子,一个web服务里包含了多个功能模块,比如其中一个功能可能会消耗大量资源和时间,当用户调用这个功能的时候,可能会影响到其他功能的正常使用,这个时候,如果把各个功能模块分出来单独部署,然后通过h

  • 深入浅析Spring-boot-starter常用依赖模块

    Spring-boot的2大优点: 1.基于Spring框架的"约定优先于配置(COC)"理念以及最佳实践之路. 2.针对日常企业应用研发各种场景的Spring-boot-starter自动配置依赖模块,且"开箱即用"(约定spring-boot-starter- 作为命名前缀,都位于org.springframenwork.boot包或者命名空间下). 应用日志和spring-boot-starter-logging 常见的日志系统大致有:java.util默认提

  • SpringBoot 监控管理模块actuator没有权限的问题解决方法

    SpringBoot 1.5.9 版本加入actuator依赖后,访问/beans 等敏感的信息时候报错,如下 Tue Mar 07 21:18:57 GMT+08:00 2017 There was an unexpected error (type=Unauthorized, status=401). Full authentication is required to access this resource. 肯定是权限问题了.有两种方式: 1.关闭权限:application.prop

  • springboot 监控管理模块搭建的方法

    Spring-Actuator是Spring-boot对应用监控的集成模块,提供了我们对服务器进行监控的支持,使我们更直观的获取应用程序中加载的应用配置.环境变量.自动化配置报告等. 使用Spring-Actuator 1.引入Maven依赖 <!-- 监控管理模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starte

  • SpringBoot+Maven 多模块项目的构建、运行、打包实战

    本篇文章主要介绍了SpringBoot+Maven 多模块项目的构建.运行.打包,分享给大家,具体如下: 项目使用的工具: IntelliJ IDEA JDK 1.8 apache-maven-3.3.9 项目的目录: 主项目 springboot-multi 子模块 entity.dao.service.web 一.使用IDEA创建一个SpringBoot项目 : File -> new -> Project 项目名称为springboot-multi 二.删除项目中的src目录,把pom.

  • spring boot添加新模块的方法教程

    前言 在springboot项目框架里,把一个项目两大模块,主项目main和测试项目test,而我们的测试项目根据功能又可以再分,比如可以有单元测试,集成测试,业务测试等等. 对于一个初学者来说,建立模块的方式需要我们掌握,网上的资料不多,很少讲到这个功能点,大叔在这里普及一下! springboot项目基本结构如图: 下面我们来建立一个集成测试模块intTest,有的团队愿意叫它integTest,都可以,intTest这个名字来自于gradle官方的文档上,大叔也借鉴一下(https://d

  • 详解Maven 搭建spring boot多模块项目(附源码)

    本文介绍了Maven 搭建spring boot多模块项目,分享给大家,具体如下: 备注:所有项目都在idea中创建 1.idea创建maven项目 1-1: 删除src,target目录,只保留pom.xml 1-2: 根目录pom.xml可被子模块继承,因此项目只是demo,未考虑太多性能问题,所以将诸多依赖.都写在根级`pom.xml`,子模块只需继承就可以使用. 1-3: 根级pom.xml文件在附录1 1-4: 依赖模块 mybatis spring-boot相关模块 2.创建子模块(

  • SpringBoot创建maven多模块项目实战代码

    工作中一直都是一个人奋战一人一个项目,使用maven管理,看这个也挺好,但是总感觉没有充分发挥maven的功能,于是研究了一下这个,网上关于这个的文章很多,虽然不是很好,但我从中收获了很多,在这集百家所长,写一份实战记录,大家跟着我一块做吧! 声明:构建多模块不是最难的,难点是如果把多模块打包成一个执行jar. SpringBoot官方推崇的是富jar,也就是jar文件启动项目,所以如果在这里打war包我不具体介绍,如果需要的朋友可以给我留言,我回复. 建议clone项目后,在看教程(有不足的地

  • springboot 多模块将dao(mybatis)项目拆分出去

    前言: 以前我们在建项目的时候, 要么将所有的package建在一个项目里面, 在处理引用的时候, 真的很方便. 不用担心, 有些东西配置不到或者读取不到. 或者, 将package独立出去, 到一个项目中或者子项目中. 这时候, 项目中的引用处理, 还是有些麻烦的. 不过好处更多, 不再表述. 在 idea 里面, 推荐使用 多模块 建项目, 而不再是 eclipse 里面的那种方式. 那这里, 就试着将一个springboot 的项目拆分到子模块中去, 看看效果如何. 项目拆分: 1. 目录

  • springboot+gradle 构建多模块项目的步骤

    springboot用以进行web项目开发的便捷性,本文不再赘述,主要是想将工作中基于springboot与gradle的多模块项目的构建经验进行总结与归纳. 1.创建项目 首先安装java和gradle,本文选用的java版本为1.8.0_40,gradle版本为2.10,安装过程本文不再赘述. 其次创建项目,名称为 springboot-mm: mkdir springboot-mm cd springboot-mm gradle init 此时的项目结构如下: 接下来,创建多个模块,这里以

随机推荐