【问题标题】:Spring-Boot multi module unable to read properties file from another moduleSpring-Boot 多模块无法从另一个模块读取属性文件
【发布时间】:2019-03-11 09:50:09
【问题描述】:

我已经搜索了高低,但我仍然无法找到这个非常烦人的问题的简单答案,

我遵循了这个很棒的指南: JWT with multi service app 一切都很好,但在指南的最后,我们建议创建一个 config-service(module) ,我已经这样做了。

问题是我无法覆盖 JwtConfig 类的默认配置

项目结构如下:

-config-service 

    | JwtConfig.java
     \
        | resources 
        \
         | jwtConfig.properties

 -other-service (add dependency in the pom file of the config-service)
     |
       someOtherclass.java (import the JwtConfig class & using @Bean to initialize )

JwtConfig 类:

/*all the imports*/ 
@PropertySource(value = "classpath:jwtConfig.properties")
public class JwtConfig {

@Value("${security.jwt.uri:/auth/**}")
private String Uri;

@Value("${security.jwt.header:Authorization}")
private String header;

@Value("${security.jwt.prefix:Bearer }")
private String prefix;

@Value("${security.jwt.expiration:#{24*60*60}}")
private int expiration;

@Value("${security.jwt.secret:JwtSecretKey}")
private String secret;

 //getters

someOtherclass.java:

/*imports*/

@Configuration
@EnableWebSecurity
public class SecurityCredentialsConfig  extends WebSecurityConfigurerAdapter 
{ 

   private JwtConfig jwtConfig; 

   @Autowired
   public void setJwtConfig(JwtConfig jwtConfig) {
       this.jwtConfig = jwtConfig;
   }
   @Bean
   public JwtConfig jwtConfig() {
    return new JwtConfig();
   }
   /*other code*/

问题是我在jwtConfig.properties文件中放什么参数并不重要,

例如:

   security.jwt.uri=test 

当其他服务加载它时,它不会出现在 JwtConfig bean 中。

只加载默认的@Value。

有人可以给点建议吗?我该如何解决? 非常感谢!

【问题讨论】:

  • @Mikhail,对不起,我有点困惑,我应该在哪里使用 PropertySources 注释?你能提供一个小例子吗,我没能从你的回答中理解它

标签: maven spring-boot multi-module application.properties java-11


【解决方案1】:

查看 Mikhail Kholodkov 的帖子后(谢谢!),

解决方法是在using服务执行点添加如下注解:

 @PropertySources({
    @PropertySource("classpath:jwtConfig.properties"),
    @PropertySource("classpath:app.properties")
})
public class OtherServiceApplication {
public static void main(String[] args) {
    SpringApplication.run(OtherServiceApplication.class, args);
    }
}

【讨论】:

    【解决方案2】:

    我认为不是使用 @PropertySources ,更好的方法和更合适的方法是在包含“主要方法”的模块中使用 @ComponentScan。由于您需要 JWTConfiguration 类的实例而不是实际的 .property 文件,因此更建议公开 bean 并让 springboot 从另一个模块扫描它,而不是公开属性文件(因为这使得另一个模块中的 jwtConfiguration.java 文件相当无用。)所以你可以尝试这样的事情

    假设我们有两个模块 - 主模块内的 Module1 和 Module2(只有 pom)。我想你知道无代码模块只是将应用程序打包为“pom”并在内部描述依赖模块的练习

    你的主要 pom

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>XXX</groupId>
        <artifactId>XXXX</artifactId>
        <packaging>pom</packaging>
        <version>1.0</version>
        <name>ws-cms-engine</name>
        <url>http://maven.apache.org</url>
        <properties>
            <spring-boot.version>2.0.0.RELEASE</spring-boot.version>
            <spring-kafka.version>2.2.3.RELEASE</spring-kafka.version>
        </properties>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <!-- Import dependency management from Spring Boot -->
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
    ............
    ............
        <modules>
          <module>Module1</module>
          <module>Module2</module>
        </modules>
    

    现在让我们考虑一下您的 JWTConfiguration 位于 Module1 中,它使用声明的资源文件夹中的属性文件 - application.properties

    JWTConfiguation.java 文件示例

    package common.module2.config
    @Configuration
    @PropertySources("classpath:application.properties")
    public class JWTConfiguration{
    
      @Value("${config1}")
      private String someConfig;
    
    
    }
    

    现在,如果您的 Module2 具有需要使用此配置的主类,那么可能这样的事情会有意义

    我们需要让 SpringBoot 容器从 module1 中声明的 bean 中读取,而不是读取实际的属性文件

    @ComponentScan(basepackages={"common.module2.config", "common.module1.this.config"})
    @SpringBootApplication
    public class Application(){
        public static void main(String args[]){
         SpringApplication.run(Application.class);
       }
    }
    

    所以这里我们通知module2包中声明的beans在启动和初始化时需要被spring容器扫描

    现在您可以在所需服务中自动装配 bean 并使用它

    @Service
    public class SampleService{
       @Autowired
       JWTConfiguration config;
    
    }
    

    这应该自动装配 JWTConfiguration 的托管实例供您使用

    【讨论】:

    • 请关闭 artifactId 打开 xml 选项卡,我最终使用了 spring 的配置服务器,恕我直言,它是目前为任何环境、单体或微服务提供配置(带有配置文件)的最佳解决方案
    • @RoieBeck 谢谢。我在 stackoverflow 中输入了代码,因此没有查看闭包。我已经纠正了。使用 spring boot cloud 实际上也是最好的方法。这是一个非常受欢迎的补充。如果可能的话,您也可以发布您的答案。
    猜你喜欢
    • 2020-03-20
    • 2018-03-28
    • 2022-09-27
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多