Мультимодуль Spring-Boot не может прочитать файл свойств из другого модуля

Я искал высоко и низко, и все же я не могу найти простой ответ на эту очень раздражающую проблему,

Я следовал этому замечательному руководству: JWT с мультисервисным приложением Все отлично работает, но в конце руководства нам предлагают создать 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 

Он не появится в bean-компоненте JwtConfig, когда его загрузит другая служба.

Загружаются только значения @Value по умолчанию.

может у кого-нибудь есть совет? как я могу это исправить? Большое спасибо!


person Roie Beck    schedule 05.10.2018    source источник
comment
Пожалуйста, посмотрите здесь stackoverflow. com/questions/35663679/   -  person Mikhail Kholodkov    schedule 06.10.2018
comment
@Mikhail, извините, я немного запутался, где мне использовать аннотации PropertySources? Не могли бы вы привести небольшой пример, мне не удалось понять это из ответа в вашей теме   -  person Roie Beck    schedule 06.10.2018


Ответы (2)


Заглянув в пост Михаила Холодкова(Спасибо!),

Решение состоит в том, чтобы добавить следующую аннотацию к используемой точке выполнения службы:

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

Я думаю, что вместо использования @PropertySources лучшим подходом и более подходящим было бы использование @ComponentScan в вашем модуле, содержащем «основной метод». Поскольку вам потребуется экземпляр класса JWTConfiguration, а не фактический файл .property, более рекомендуется выставить bean-компонент и заставить Springboot сканировать его из другого модуля, а не выставлять файл свойств (потому что это делает файл jwtConfiguration.java в другом модуле довольно бесполезным.) Так что вы, вероятно, могли бы попробовать что-то вроде этого

Скажем, у нас есть два модуля — Module1 и Module2 внутри основного модуля (у которого есть только 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 читать из bean-компонента, объявленного в module1, а не читать фактический файл свойств.

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

Итак, здесь мы сообщаем, что bean-компоненты, объявленные в пакете module2, должны быть просканированы контейнером spring при его запуске и инициализации.

Теперь вы можете автоматически подключить bean-компонент к нужному сервису и использовать его.

@Service
public class SampleService{
   @Autowired
   JWTConfiguration config;

}

Это должно автоматически связать управляемый экземпляр JWTConfiguration, чтобы вы могли его использовать.

person vijayakumarpsg587    schedule 15.02.2019
comment
пожалуйста, закройте вкладку ArtiftId, открывающую xml, в итоге я использовал сервер конфигурации Spring, ИМХО, в настоящее время это лучшее решение для предоставления конфигурации (с профилем) для любой среды, монолита или микросервисов. - person Roie Beck; 17.02.2019
comment
@RoieBeck, спасибо. Я набрал код в stackoverflow и, следовательно, не смотрел замыкания. Я исправил это. Использование весеннего загрузочного облака на самом деле также является лучшим способом. это действительно приятное дополнение. Если возможно, вы также можете опубликовать свой ответ. - person vijayakumarpsg587; 18.02.2019