Context中嵌套<Environment>元素

本文介绍如何在Context中使用&lt;Environment&gt;元素配置环境条目,使其在整个web应用中可见。这种方式无需修改部署描述符即可定制环境条目的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境条目 
可以在Context中嵌套<Environment>元素,配置命名的值,这些值作为环境条目资源(Environment Entry Resource),对整个web应用可见。比如,可以按照如下方法创建一个环


境条目:


<Context ...> 
... 
<Environment name="maxExemptions" value="10" 
type="java.lang.Integer" override="false"/> 
... 
</Context>


这与在/WEB-INF/web.xml中包含如下元素是等价的:


<env-entry> 
<env-entry-name>maxExemptions</param-name> 
<env-entry-value>10</env-entry-value> 
<env-entry-type>java.lang.Integer</env-entry-type> 
</env-entry>




区别是,前者不需要修改deployment descriptor来定制这个值。


<Environment>元素的有效属性所如下:


属性 描述 
description 环境条目的文字描述(可选)


name 环境条目的名称,相对于java:comp/env context。


override 如果不希望/WEB-INF/web.xml中具有相同名称的<env-entry>覆盖这里指定的值,设为false。缺省值为true。


type 环境条目的Java类名的全称.在/WEB-INF/web.xml中,<env-entry-type>必须是如下的值:java.lang.Boolean, java.lang.Byte, java.lang.Character, java.lang.Double,


java.lang.Float, java.lang.Integer, java.lang.Long, java.lang.Short, or java.lang.String.


value 通过JNDI context请求时,返回给应用的参数值。这个值必须转换成type属性定义的Java类型
use clap::Parser; use serde::Deserialize; use std::fs; use toml; use chrono::NaiveDate; use anyhow::{Context, Result}; #[derive(Parser)] pub struct Cli { #[arg(short, long, default_value_t = String::from("http://localhost:4242"))] pub url: String, #[arg(short, long)] pub config: Option<std::path::PathBuf>, #[arg(short, long)] pub units: Vec<u32>, #[arg(short, long)] pub start_date: NaiveDate, #[arg(short, long)] pub end_date: NaiveDate, #[arg(short, long, default_value_t = String::from("./backup"))] pub backup_dir: String, #[arg(short, long, default_value_t = 1)] pub concurrency: usize, #[arg(short, long, default_value_t = 7)] pub interval_days: u64, #[arg(short, long)] pub metrics: Vec<String>, #[arg(short, long, action = clap::ArgAction::SetFalse)] pub compress: bool, } #[derive(Deserialize)] pub struct Config { pub url: Option<String>, pub units: Option<Vec<u32>>, pub start_date: Option<NaiveDate>, pub end_date: Option<NaiveDate>, pub backup_dir: Option<String>, pub concurrency: Option<usize>, pub interval_days: Option<u64>, pub metrics: Option<Vec<String>>, pub compress: Option<bool>, } impl Config { pub fn load_config(path: &Option<std::path::PathBuf>) -> Result<Self> { match path { Some(p) => { let contents = fs::read_to_string(p).context("Failed to read config file")?; toml::from_str::<Self>(&contents).context("Failed to parse config") }, None => Ok(Config::default()), } } pub fn merge_configs(cli: &Cli) -> Result<Self> { let config = Self::load_config(&cli.config)?; Ok(Self { url: cli.url.clone()(|| config.url.clone()).unwrap_or_else(|| "http://localhost:4242".to_string()), units: if !cli.units.is_empty() { Some(cli.units.clone()) } else { config.units.clone() }, start_date: cli.start_date.or(config.start_date.ok_or(anyhow::anyhow!("Start date must be provided"))?)?, end_date: cli.end_date.or(config.end_date.ok_or(anyhow::anyhow!("End date must be provided"))?)?, backup_dir: Some(cli.backup_dir.clone().or_else(|| config.backup_dir.clone().unwrap_or_else(|| "./backup".to_string()))), concurrency: Some(cli.concurrency.max(config.concurrency.unwrap_or(1))), interval_days: Some(cli.interval_days.max(config.interval_days.unwrap_or(7))), metrics: if !cli.metrics.is_empty() { Some(cli.metrics.clone()) } else { config.metrics.clone() }, compress: Some(cli.compress && config.compress.unwrap_or(true)), }) } } impl Default for Config { fn default() -> Self { Config { url: None, units: None, start_date: None, end_date: None, backup_dir: None, concurrency: None, interval_days: None, metrics: None, compress: None, } } }
07-30
package com.hw.camunda.config.datasource; import com.baomidou.dynamic.datasource.creator.DataSourceProperty; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import com.hw.camunda.utils.Sm4Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.HashSet; @Configuration public class DataSourceDecryptConfig { @Autowired private Environment env; @Bean public DynamicDataSourceProperties dynamicDataSourceProperties() { DynamicDataSourceProperties properties = new DynamicDataSourceProperties(); // 动态获取主数据源名称 String primaryName = env.getProperty("spring.datasource.dynamic.primary"); properties.setPrimary(primaryName); // 动态获取所有数据源名称 Set<String> dataSourceNames = getDataSourceNames(); // 解密所有数据源 Map<String, DataSourceProperty> dataSources = new HashMap<>(); for (String name : dataSourceNames) { dataSources.put(name, decryptDataSource("spring.datasource.dynamic.datasource." + name)); } properties.setDatasource(dataSources); return properties; } // 动态获取所有数据源名称 private Set<String> getDataSourceNames() { Set<String> names = new HashSet<>(); String prefix = "spring.datasource.dynamic.datasource."; if (env instanceof AbstractEnvironment) { MutablePropertySources sources = ((AbstractEnvironment) env).getPropertySources(); for (PropertySource<?> source : sources) { if (source instanceof org.springframework.core.env.MapPropertySource) { for (String name : ((org.springframework.core.env.MapPropertySource) source).getPropertyNames()) { if (name.startsWith(prefix)) { // 提取数据源名称:prefix后的第一个部分 String[] parts = name.substring(prefix.length()).split("\\."); if (parts.length > 0) { names.add(parts[0]); } } } } } } return names; } private DataSourceProperty decryptDataSource(String prefix) { DataSourceProperty dsProp = new DataSourceProperty(); dsProp.setUrl(decrypt(env.getProperty(prefix + ".url"))); dsProp.setUsername(decrypt(env.getProperty(prefix + ".username"))); dsProp.setPassword(decrypt(env.getProperty(prefix + ".password"))); // 处理其他可能存在的属性 String driver = env.getProperty(prefix + ".driver-class-name"); if (driver != null) { dsProp.setDriverClassName(driver); } return dsProp; } private String decrypt(String encryptedText) { if (encryptedText == null) return null; // 调用解密工具 - 实际实现需替换为您的解密逻辑 try { return new String(Sm4Util.decrypt(encryptedText.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { throw new RuntimeException(e); } } } 帮我修复一下,我是动态的多数据源
最新发布
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值