小编典典

Spring Boot属性将在初始化时加载并尊重所有内容,并基于属性文件中的值控制@Aspect

spring-boot

我们正在使用从外部文件加载属性@PropertySources。现在,我想@Aspect基于属性启用/禁用。我尝试使用@ConditionalOnExpression不起作用。我尝试通过创建Bean来尝试相同的操作propertyplaceholderconfig。即使在同一情况下,它也不起作用。然后,我尝试了@profile最初也不起作用的方法。

我弄清楚的是,当启动时使用propertysourcepropertyplaceholderbean
时,这些变量在启动时并未初始化。有些变量总是被忽略,例如(logging.file)。但是@Value效果很好。为了设置这些变量,我必须将它们作为JVM参数传递。

所以我的问题是:
1.如何使spring在启动时始终读取指定的属性文件并尊重它们?
2.这是启用/禁用的最佳方法@Aspect。使用@profile@ConditionalOnExpression或其他?

目前,我们正在设置logging.filemain方法,因为它的行为也相同。但是你们知道这不是正确的方法,因为我最终可能会像这样逐个添加属性。我想将所有属性放入外部文件,以便spring读取这些文件并设置其属性。

我们的财产结构:

  1. common.properties#这具有所有公共属性
  2. service.properties#特定于服务的属性。这还将包含common.properties中的现有属性,这些属性将被覆盖。

我了解我可以使用个人资料。但是,我们希望将属性保留在外部,以便在更改属性时需要重新启动服务。我也不想将变量作为JVM参数传递,那么我必须以这种方式传递大多数变量。传递-
Dspring.config.location也是困难的,因为common.propertiesservice.properties使用和“service.properties”文件名的每个服务而不同。

示例代码:

主类:

@PropertySources({
        @PropertySource(value = "file:${property_path}/common.properties", ignoreResourceNotFound = false),
        @PropertySource(value = "file:${property_path}/service1.properties", ignoreResourceNotFound = true) })
public class MainClass {
static String logDirectory = ApplicationContext.getGlobalProperty("logging.file");

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(MainClass.class);

        Properties properties = new Properties();
        properties.put("logging.file", logDirectory);
        springApplication.setDefaultProperties(properties);
        springApplication.run(args);
    }
}

应用环境:

@Configuration
@EnableAutoConfiguration
public class ApplicationContext implements EnvironmentAware {

    private static Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        ApplicationContext.environment = environment;
    }
    public static String getGlobalProperty(String propertyName) {
    return environment.getProperty(propertyName);
    }
}

在这里你可以看到我用什么办法environment来获得property。是否有任何方法可以使用环境设置属性,以便在进行Spring
Boot初始化本身时填充属性?

我们还可以实现ApplicationContextInitializer和重写initialize方法以读取属性。但是,如何使它读取2个属性文件并用最新值覆盖重复属性?参考(我不知道如何实现我这样的要求)。即使在这种情况下,听起来也不像您想用锤子杀死蚊子吗?

当前工作解决方案:

@Aspect
@Profile("!production")
@Configuration
public class ControllerAspect {
@pointcut(....)
} //Here also I've to pass spring.profiles.active as JVM params.
//setting the value in common.properties or service1.properties is not working.

我是弹簧靴的新手,所以请给我进一步的说明。


阅读 479

收藏
2020-05-30

共1个答案

小编典典

看来Spring默认情况下会在初始化时加载一些属性,除非您明确编写了覆盖它们的逻辑
(如我所写的那样MainClass.java
,否则没有任何选项可以覆盖这些属性。其中一些包括(logging.file,@
ConditionalonExpression中使用的键)。

自身挑战的一些技巧:

  1. application.properties在类路径中指定属性。始终从此文件中读取在较早阶段加载的变量。 挑战:我已将所有属性紧密耦合到jar中,并且为了更改值,我不得不重新编译并重新启动Jar。
  2. 使用配置文件并将其定义application.propertiesapplication-profile.properties 挑战:我必须创建这么多配置文件,但仍然存在先前的挑战。
  3. 将属性值作为JVM参数传递-Dproperty.key=value 挑战:认真吗? 我应该作为JVM参数发送多少个属性?
  4. 实现ApplicationContextInitialize和重写initialize方法。 挑战:不建议重写Spring的默认行为,并且仅使用此行为读取属性文件是否不是一个过大的杀伤力?

解:

使用-Dspring.config.location指定属性的文件。在这种情况下,始终spring仅从指定的位置读取属性。您也可以提供多个属性文件。
请参阅此以获取更多详细信息。
似乎如果您提供属性位置,则目录会以相反的顺序弹簧加载它们。但是,如果指定文件,则遵循指定的顺序。

注意:所有这些都可以合并在一起。 要了解优先级,请参考此

2020-05-30