简体   繁体   English

在将Spring解析的属性注入bean之前,如何对其进行修改

[英]How to modify properties resolved by Spring before their injection into beans

I need to provide support for external preperties decryption in Spring application. 我需要为Spring应用程序中的外部属性解密提供支持。 I planned to use a mechanism from spring-cloud-config , which is triggered after the Environment is ready and add decrypted properties with higher precedence. 我计划使用spring-cloud-config中的一种机制,该机制在Environment准备就绪后触发,并添加具有更高优先级的解密属性。 Unfortunately it heavily relies on Spring Boot bootstrap mechanism which emits ApplicationEnvironmentPreparedEvent . 不幸的是,它严重依赖于Spring Boot引导机制,该机制会发出ApplicationEnvironmentPreparedEvent Looking into the Spring Framework code the environment and context creation is highly coupled and it would be rather hard to run my own code between that. 查看Spring Framework代码,环境和上下文创建是高度耦合的,并且在它们之间运行我自己的代码将相当困难。 The application I am working with is a large, multi module "standard" Spring MVC application and I would not like to convert it into Spring boot application right now. 我正在使用的应用程序是一个大型的,多模块的“标准” Spring MVC应用程序,我现在不希望将其转换为Spring引导应用程序。

Question : 问题

How could I execute my code after the environment was created and before the context creation (to modify properties before they will be injected into "normal" beans) in Spring ( not Spring Boot ) application? 在Spring( 不是Spring Boot )应用程序中,在创建环境之后以及在创建上下文之前(在将属性注入到“普通” bean中之前修改属性)之前,我如何执行代码?

Alternative question : 替代问题

Is there any other way to get control over properties being injected into beans (for modify values originally resolved by Spring)? 还有其他方法可以控制注入到bean中的属性(用于修改最初由Spring解析的值)吗?

You can create a custom ApplicationContextInitializer which adds decryption or whatever to the PropertySource s of your choice. 您可以创建一个自定义ApplicationContextInitializer ,以向您选择的PropertySource添加解密或其他内容。

We do something similair in one of the application I currently develop. 我们在当前开发的应用程序中做了一些类似的事情。 After loading some custom properties from files and databases we wrap all the available PropertySource s in a EncryptablePropertySource because several properties are encrypted (We use the Jasypt library for that). 从文件和数据库加载一些自定义属性后,我们将所有可用的PropertySource包装在EncryptablePropertySource因为已加密了多个属性(为此,我们使用Jasypt库)。

Use @Value("${propname}") annotation on a setter method, instead of using on the field. 在setter方法上使用@Value("${propname}")批注,而不是在字段上使用。

You can write code to handle transform/validate the property in the setter method, and then assign to the field. 您可以编写代码来处理setter方法中的变换/验证属性,然后将其分配给该字段。

In the mean time I have found customizeContext method in ContextLoader which reads defined ApplicationContextInitializer s. 在平均时间我已经发现customizeContext在方法ContextLoader其中读取定义ApplicationContextInitializer秒。 It is executed after the environment was created and before the context is reloaded, so decryption in an initializer should work (at least in the base case): 它是在创建环境之后且重新加载上下文之前执行的,因此初始化程序中的解密应该起作用(至少在基本情况下):

ConfigurableEnvironment env = wac.getEnvironment();
(...) 
customizeContext(sc, wac);
wac.refresh();

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM