Spring引导体系结构可减少应用程序部件中的依赖性
我们有一个基于spring引导的应用程序/应用程序集合。在第一句话中,正确描述它已经很复杂了,因为从业务的角度来看,“东西”是一个应用程序,但从技术的角度来看,它是一个spring引导应用程序和批处理作业的集合,处理一个业务软件的用例 例如,该软件由一个提供RESTAPI的spring boot应用程序、多个提供不同web服务的spring boot应用程序和多个基于spring boot应用程序和其他应用程序执行不同操作的批处理作业组成。 现在代码的某些部分只从一个spring boot应用程序中使用,因此可以很容易地定位到这个特定的spring boot应用程序中。 但是代码的许多部分是从多个spring引导应用程序中使用的,但通常少于应用程序的一半。对于这个业务代码,我们有一个由所有spring引导应用程序导入的中心模块。将此中心模块添加到spring boot应用程序会增加大量依赖项(例如,对CRM系统的依赖项、对S3存储的依赖项、对生成Excel文件的依赖项、对外部Web服务的依赖项、对兔子的依赖项等等)。为了避免数以百计的依赖关系,我们将许多依赖关系定义为可选的。因此,每个spring引导应用程序都只有它所需要的依赖项 现在的问题是中央模块中使用业务代码实现的服务。这些服务由autowire注入。例如,提供webservice接口的spring引导应用程序不需要该服务来生成Excel文件,也不需要依赖Excel库,也不需要启动Excel生成服务 Spring可以使用@ConditionalOnClass和@ConditionalOnBean对服务进行注释,但许多服务不仅依赖于一个条件,还依赖于两个或多个条件。 那么,只有在需要和/或需要的依赖项可用时,构建服务以启动它们的最佳方法是什么 目前,我们在每个spring引导应用程序中使用@ComponentScan和excludeFilters,但这很容易出错。将中央模块拆分为多个模块或微服务是不可取的,因为这样模块只包含1到5个类Spring引导体系结构可减少应用程序部件中的依赖性,spring,spring-boot,dependency-injection,autowired,Spring,Spring Boot,Dependency Injection,Autowired,我们有一个基于spring引导的应用程序/应用程序集合。在第一句话中,正确描述它已经很复杂了,因为从业务的角度来看,“东西”是一个应用程序,但从技术的角度来看,它是一个spring引导应用程序和批处理作业的集合,处理一个业务软件的用例 例如,该软件由一个提供RESTAPI的spring boot应用程序、多个提供不同web服务的spring boot应用程序和多个基于spring boot应用程序和其他应用程序执行不同操作的批处理作业组成。 现在代码的某些部分只从一个spring boot应用程
有没有像这样构造应用程序的好方法?您已经很好地理解了这个问题,并将其分解为足够多的模块。在您的案例中,要解决将@ComponentScan与excludeFilters一起使用的问题,您必须尝试使用Spring Boot的自动配置机制来完成这项工作 例如,在属性或yaml文件中配置数据源,并且Spring Boot JPA Starter在类路径中,Spring Boot自动为我们配置一切。您需要编写一些带有逻辑的自定义启动器,以便根据您的多种条件自动配置您的服务。在您的微服务、批处理作业中,您可以包含此自定义启动器,以启用和注入必要的服务以及单独的服务
不久前,我写了两篇关于如何编写定制Spring启动程序的博客文章。这对你来说可能是个好的开始。而且。您已经很好地理解了这个问题,并将其分解为足够多的模块。在您的案例中,要解决将@ComponentScan与excludeFilters一起使用的问题,您必须尝试使用Spring Boot的自动配置机制来完成这项工作 例如,在属性或yaml文件中配置数据源,并且Spring Boot JPA Starter在类路径中,Spring Boot自动为我们配置一切。您需要编写一些带有逻辑的自定义启动器,以便根据您的多种条件自动配置您的服务。在您的微服务、批处理作业中,您可以包含此自定义启动器,以启用和注入必要的服务以及单独的服务
不久前,我写了两篇关于如何编写定制Spring启动程序的博客文章。这对你来说可能是个好的开始。和。如果您的模块将公共模块声明为依赖项,则可以将该模块的范围设置为“编译”,然后设置应从公共模块中排除的依赖项 我最近遇到一种情况,我需要在我的公共模块中使用JPA,以便为其他模块创建通用DAO。但我认为在我的另一个没有使用JPA的模块中添加这么大的依赖项是浪费的 这就是解决方案:
<!-- ... -->
<groupId>com.multimodule</groupId>
<artifactId>server-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.version}</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>com.multimodule</groupId>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</exclusion>
<exclusion>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ... -->
</dependencies>
<!-- ... -->
com.multimultimule
服务器应用程序
1.0.0-SNAPSHOT
罐子
org.springframework.boot
spring启动程序父级
${spring.version}
com.multimultimule
常见的
1.0.0-SNAPSHOT
编译
org.springframework.boot
spring引导启动器数据jpa
com.microsoft.sqlserver
mssql jdbc
通过这样做,除了使用@ComponentScan
排除公共模块中与JPA相关的包外,在服务器应用程序模块编译时还包括公共依赖项,但不包括JPA JAR
如果未添加@ComponentScan
,则模块仍将编译,但一旦从公共连接bean,尝试从任何排除的jar连接bean,则可能会出现异常
在我的例子中,这是正确的,因为我的公共模块会在启动时尝试自动配置Jpa,若它并没有被排除,因为
@springbootplication
中的@EnableAutoConfiguration
如果您的模块将公共模块声明为依赖项,则可以将该模块的作用域设置为“compile”,然后设置依赖项