Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring引导体系结构可减少应用程序部件中的依赖性_Spring_Spring Boot_Dependency Injection_Autowired - Fatal编程技术网

Spring引导体系结构可减少应用程序部件中的依赖性

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应用程

我们有一个基于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个类


有没有像这样构造应用程序的好方法?

您已经很好地理解了这个问题,并将其分解为足够多的模块。在您的案例中,要解决将@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”,然后设置依赖项