简体   繁体   English

在初始化时加载 Spring 引导属性,并根据属性文件中的值尊重所有和控制 @Aspect

[英]Spring boot properties to be loaded at initialization and respect all and control @Aspect based on the value from property file

We are loading properties from an external file using @PropertySources .我们正在使用@PropertySources从外部文件加载属性。 Now I want to enable/disable @Aspect based on a property.现在我想根据属性启用/禁用@Aspect I tried using @ConditionalOnExpression which didn't work.我尝试使用@ConditionalOnExpression但没有用。 I tried the same by creating a bean of propertyplaceholderconfig .我通过创建propertyplaceholderconfig的 bean 尝试了同样的方法。 Even in the same case, it didn't work.即使在相同的情况下,它也不起作用。 Then I tried @profile which also didn't work initially.然后我尝试了@profile ,它最初也不起作用。

What I Figured out is that these variables are not initialized at the starting when propertysource or propertyplaceholder bean is used at startup.我发现这些变量在启动时使用propertysourcepropertyplaceholder bean 时没有初始化。 Some variables are always ignored like (logging.file).某些变量总是被忽略,例如 (logging.file)。 But @Value works fine.@Value工作正常。 In order to set these variables, I've to pass them as JVM parameters.为了设置这些变量,我必须将它们作为 JVM 参数传递。

So my questions are:所以我的问题是:
1. How can I make spring to always read specified property files at startup and respect all of them? 1.如何让spring在启动时始终读取指定的属性文件并尊重所有这些文件?
2. Which is the best way to enable/disable @Aspect . 2. 启用/禁用@Aspect的最佳方法是什么。 Using @profile or @ConditionalOnExpression or something else?使用@profile@ConditionalOnExpression或其他什么?

Currently, we are setting logging.file in the main method since this also behaves the same way.目前,我们正在 main 方法中设置logging.file因为这也以相同的方式运行。 But you guys know that it's not the proper way as I may end up adding the properties one by one like this.但是你们知道这不是正确的方法,因为我最终可能会像这样一个一个地添加属性。 I want to put all the properties into external files such that spring reads those files and sets its properties.我想将所有属性放入外部文件中,以便 spring 读取这些文件并设置其属性。

Our properties structure:我们的物业结构:

  1. common.properties #This has all common properties common.properties #这具有所有公共属性
  2. service.properties #Property specific to a service. service.properties #特定于服务的属性。 This will also contain existing property from common.properties which will be overridden.这也将包含来自 common.properties 的现有属性,这些属性将被覆盖。

I understand that I can use profiles.我知道我可以使用配置文件。 But, we want to keep the properties outside such you need to restart service if you are changing the properties.但是,我们希望将属性保留在外部,以便在更改属性时需要重新启动服务。 I also don't want to pass the variables as JVM parameters then I've to pass most of the variables in this way.我也不想将变量作为 JVM 参数传递,然后我必须以这种方式传递大部分变量。 Passing -Dspring.config.location is also difficult as common.properties and service.properties are used and 'service.properties' filename varies for each service.传递 -Dspring.config.location 也很困难,因为使用了common.propertiesservice.properties并且“service.properties”文件名因每个服务而异。

sample codes:示例代码:

Mainclass:主班:

@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);
    }
}

Application Context:应用上下文:

@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);
    }
}

Here you can see any way I've used environment to get property .在这里,您可以看到我使用environment获取property任何方式。 Is there any way to set the property using the environment such that while spring boot initialization itself the properties are populated?有什么方法可以使用环境设置属性,以便在 spring boot 初始化本身时填充属性?

We can also implement ApplicationContextInitializer and override initialize method to read properties.我们还可以实现ApplicationContextInitializer并覆盖initialize方法来读取属性。 But how can I make it read 2 property files and override the duplicate property with the latest value?但是如何让它读取 2 个属性文件并使用最新值覆盖重复属性? Reference(I'm not sure how to implement my requirements in this way.) .参考(我不确定如何以这种方式实现我的要求。) Even in this case doesn't sound like you are trying to kill a mosquito with a hammer?即使在这种情况下,听起来也不像是在用锤子杀死一只蚊子?

Current working Solution:当前工作解决方案:

@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. 

I'm a newbie to spring boot so please let me know for additional clarifications.我是 Spring Boot 的新手,所以请让我知道更多说明。

It seems Spring by default loads some properties at initialization and unless until you specifically write logic to overwrite them (like the one I wrote in MainClass.java ) there is no option to override those.似乎 Spring 在初始化时默认加载一些属性,除非您专门编写逻辑来覆盖它们(就像我在MainClass.java编写的MainClass.java ,否则没有选项可以覆盖这些。 Some of these include (logging.file, key used in @ConditionalonExpression).其中一些包括(logging.file,@ConditionalonExpression 中使用的键)。

Some tricks with their own challenges:一些有自己挑战的技巧:

  1. Specify the properties in application.properties in your classpath.在类路径中的application.properties中指定属性。 The variables loaded at the earlier stages are always read from this file.在早期阶段加载的变量总是从这个文件中读取。 challenge: I've tight coupled all my properties into the jar and in order to change the values I've to recompile and relaunch the Jar.挑战:我已将所有属性紧密耦合到 jar 中,为了更改值,我必须重新编译并重新启动 Jar。
  2. Use profiles and define application.properties as application-profile.properties .使用配置文件并将application.properties定义为application-profile.properties challenge: I've to create so many profiles and still the previous challenge exists.挑战:我必须创建如此多的配置文件,但之前的挑战仍然存在。
  3. Pass the property value as JVM parameter as -Dproperty.key=value .将属性值作为 JVM 参数传递为-Dproperty.key=value challenge:seriously?挑战:认真的? How many properties am I supposed to send as JVM parameter?我应该发送多少个属性作为 JVM 参数?
  4. Implement ApplicationContextInitialize and override initialize method.实现ApplicationContextInitialize并覆盖initialize方法。 challenge:Overriding Spring's default behaviour is not recommended as well as isn't it an overkill to use this just for reading property file?挑战:不建议覆盖 Spring 的默认行为,并且仅将其用于读取属性文件是否过于矫枉过正?

Solution:解决方案:

Use -Dspring.config.location to specify the property files.使用-Dspring.config.location指定属性文件。 In this case, always spring reads the properties only from the specified location(s).在这种情况下,弹簧始终仅从指定位置读取属性。 You can provide multiple property files as well.您也可以提供多个属性文件。 Refer this for much more details. 有关更多详细信息,请参阅此处。 It seems if you give property locations as Directories spring loads them in reverse order.似乎如果您将属性位置作为目录弹簧以相反的顺序加载它们。 But if you specify files it follows the order specified.但是,如果您指定文件,它会遵循指定的顺序。

Note: All these can be combined together.注意:所有这些都可以组合在一起。 To know about precedence refer this . 要了解优先级,请参阅此

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Spring 表达式语言断言从属性文件加载的属性(用逗号分隔的值)是否包含“值” - Using Spring expression language to assert if a property (with comma separated values) loaded from a properties file, contains “value” Spring 引导从属性文件中获取所有属性并加载到 hashmap - Spring boot get all properties from properties file and load into hashmap 如何从 spring boot 项目的 application.properties 文件中获取属性值? - How to get property value from application.properties file on spring boot project? 属性值未使用 spring 引导从 application.properties 解析 - property value not resolved from application.properties using spring boot Spring Boot:从另一个属性文件读取数据源属性 - Spring Boot: Read Datasource properties from another property file Spring 引导:全局访问从自定义属性表加载的属性的方法 - Spring Boot : approach to have global access to properties loaded from a custom property table Spring - 根据 application.properties 中的值加载自定义属性文件 - Spring - Load custom property file based on value from application.properties 根据属性值spring boot从列表中过滤对象 - Filter object from list based on property value spring boot Spring Boot-从外部属性文件设置值 - Spring Boot - set value from an external properties file Spring Boot:Spring 总是为属性分配默认值,尽管它存在于 .properties 文件中 - Spring Boot : Spring always assigns default value to property despite of it being present in .properties file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM