Variables Dinámicas
Una variable dinámica es una definición segura en cuanto a tipos de un valor configurable que puede ser sobrescrito en tiempo de ejecución. Las variables dinámicas se definen utilizando el Marco de Reglas.DynamicValueLibrary concepto y generar a Java código que se integra con el DynamicExpressionRegistry.
Descripción general
Las variables dinámicas proporcionan una forma de externalizar la configuración de sus reglas de negocio. Cada variable dinámica tiene:
-
Un nombre del modelo- identifica cuál MPS modelar la variable a la que pertenece
-
Un nombre de variable- el nombre único dentro del modelo
-
Un tipo- the Java clase que representa el tipo de valor (primitivos o listas)
-
Un valor predeterminado- utilizado cuando no se proporciona una anulación de configuración
Cuando su MPS el modelo se compila, las variables dinámicas generan un DynamicVariable<T> registro que encapsula estos metadatos.
Seguridad de Tipo
Las variables dinámicas son de tipo fuerte. Los tipos soportados son:
-
Tipos primitivos:`Number`,
String,Boolean -
Tipos de lista:`List<Number>`,
List<String>,List<Boolean>
Este tipo de seguridad se aplica tanto en tiempo de compilación (en el código generado) como en tiempo de ejecución (al cargar los valores de configuración).
Validación de Tipo en Tiempo de Ejecución
Cuando se cargan las fuentes de configuración al inicio de la aplicación, el ConfigurableValuesManager valida que el tipo de cada valor de configuración coincida con el correspondiente DynamicVariable definición de tipo. Esta validación:
-
Ocurre al inicio- Los errores de configuración se detectan inmediatamente cuando la aplicación se carga.
-
Valida en actualizaciones de push- Las fuentes dinámicas que admiten actualizaciones en tiempo de ejecución también activan la validación.
-
Usos de la asignabilidad de tipos- Se aceptan subtipos (por ejemplo,
ArrayListparaList,IntegerparaNumber) -
Permite valores nulos- Null se considera válido y elude la verificación de tipos.
Si se detecta un desajuste de tipo, la aplicación falla rápidamente con un mensaje de error detallado:
java.lang.IllegalArgumentException: Type mismatch for configuration variable with key:
'paymentService_upperBound' - expected type java.lang.Integer but got java.lang.String
Esto asegura que los errores de configuración se detecten temprano en lugar de causar fallos en tiempo de ejecución en la lógica de negocio.
Formato Clave
Cada variable dinámica tiene una clave compuesta utilizada para búsquedas en el registro:
{modelName}_{variableName}
Por ejemplo, una variable llamada upperBound en un modelo llamado paymentService tendría la clave:
paymentService_upperBound
Este formato de clave se utiliza al configurar valores en HOCON archivos o registrándolos programáticamente.
Código Generado
Cuando usted define una variable dinámica en MPS, el generador de código crea un DynamicVariablesLibrary clase:
public class DynamicVariablesLib implements DynamicVariableLibrary {
// Static variable definitions with defaults
public static final DynamicVariable<Number> upperBound =
new DynamicVariable<>(
"paymentService", // model name
"upperBound", // variable name
Number.class, // type
BigInteger.valueOf(1000) // default value
);
public static final DynamicVariable<List<String>> allowedCurrencies =
DynamicVariable.ofList(
"paymentService",
"allowedCurrencies",
String.class,
Arrays.asList("USD", "EUR", "GBP")
);
// Singleton instance
public static DynamicVariableLibrary INSTANCE = new DynamicVariablesLibrary();
// Instance field containing all variables
private final List<DynamicVariable<?>> dynamicVariables;
// Constructor initializes the list
private DynamicVariablesLib() {
dynamicVariables = new ArrayList<>();
dynamicVariables.add(upperBound);
dynamicVariables.add(allowedCurrencies);
}
@Override
public List<DynamicVariable<?>> getDynamicVariables() {
return dynamicVariables;
}
}
El código generado también hace referencia a DynamicVariableResolver.resolve() para recuperar el valor actual en tiempo de ejecución.
DynamicVariable Registro
El DynamicVariable<T> el registro se define como:
public record DynamicVariable<T>(
String modelName,
String name,
Class<T> rawType,
Class<?> elementType,
T defaultValue
) {
// Key generation
public String key() {
return modelName + "_" + name;
}
// Factory for list types
public static <E> DynamicVariable<List<E>> ofList(
String modelName,
String name,
Class<E> elementType,
List<E> defaultValue
) { ... }
}
Flujo de Resolución
Cuando el código generado necesita un valor de variable dinámica:
-
DynamicVariableResolver.resolve(variable)se llama -
El resolutor verifica primero un valor con alcance de entidad (si existe un contexto de procesamiento)
-
Vuelve al registro global
-
Devuelve el valor predeterminado si no se encuentra ninguna anulación.
-
Convierte el valor al apropiado KernelF tipo