当前位置: 首页 > news >正文

想建设个人网站去那里建设宁德做网站的公司

想建设个人网站去那里建设,宁德做网站的公司,个人备案网站描述,最新传奇手游2022首发排行BootstrapContext是Spring Boot 2.4 版本后引入的全新引导上下文机制,‌取代了早期版本中基于BootstrapApplicationListener的配置加载模式。基于SpringClould开始了解BootstrapContext初始化。 创建DefaultBootstrapContext private DefaultBootstrapContext crea…

BootstrapContext是Spring Boot 2.4 版本后引入的全新引导上下文机制,‌取代了早期版本中基于BootstrapApplicationListener的配置加载模式。基于SpringClould开始了解BootstrapContext初始化。

创建DefaultBootstrapContext

	private DefaultBootstrapContext createBootstrapContext() {DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();// 使用BootstrapRegistryInitializer初始化DefaultBootstrapContext,SpringCloud默认提供了两个初始化程序,自己也可以实现这个接口来自定义自己的逻辑this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));return bootstrapContext;}

默认提供的两个初始化程序
在这里插入图片描述

RefreshBootstrapRegistryInitializer

	@Overridepublic void initialize(BootstrapRegistry registry) {// promote BootstrapContext to context// 注册了一个BootstrpContext close的监听器registry.addCloseListener(event -> {BootstrapContext bootstrapContext = event.getBootstrapContext();// 将bootstrapContext注册到BeanFactory中 这样我们就能通过依赖注入获取BootstrapContext event.getApplicationContext().getBeanFactory().registerSingleton("bootstrapContext", bootstrapContext);});}

TextEncryptorConfigBootstrapper

这个用于注册文本加密器使用,可以用来实现配置文件的加密功能。

使用示例

// 用来测试解密的属性
@Component
@ConfigurationProperties(prefix = "test")
@Data
public class TestConfig {/*** testName*/private String testName;
}@Component
@RequiredArgsConstructor
public class TestTextEncryptor implements ApplicationRunner {// 文本加密器private final TextEncryptor textEncryptor;// Environment private final Environment environment;// BootstrapContext private final BootstrapContext bootstrapContext;@Overridepublic void run(ApplicationArguments args) throws Exception {// 加密字符串 这个配置在配置文件中System.out.println(textEncryptor.encrypt("加密测试"));// 将属性绑定到TestConfig类中 bootstrapContext中提供了BindHandler 可以直接在绑定属性的时候实现解密TestConfig test = Binder.get(environment).bindOrCreate("test", Bindable.of(TestConfig.class), bootstrapContext.get(BindHandler.class));System.out.println("test = " + test);}}

application.yml配置

# 这里配置RSA密钥 这样就会启用RSA的加密器 不包含这个RSA PRIVATE KEY使用Aes加密器
encrypt:key: '-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDfgBRrvCH0U24TLv38RtESTU9r3KmaxZ9s49sKcLBAch0+OWQfHNidyQA1z+uGdJpU2Bgh0Is8/vWBae1Q3o/map2vShXv6BwE3aWzfF1mz6ZoYtb1tEy/0OBZ6Sa5K0gdFGM/czfG4tBF9anZ3N6h0WBW1/sR2ZnIViJtQJCy7QIDAQABAoGAZFPPVulV6KKG+A+RLezwLyILM+UTMYni3fOOwSoCxHs1S1hh7GF7j6DJ+l4CYRH4sXtrocpGprPgqx5MzI+L0lFrLPL+XldfMJkPjtP0tBAS3e9CtbO2cuY9sBkE/KbxfW5Uwfe4X6iy7s1MO+oynR+6ITDTjJRUgk8alGAKJYECQQDvrJs3GzttkrM9woDEAP0ZZOp49RJd526AXmEmPW8W8YvHRrSkWl8IUiA8ciwJzqTFkBbd0IWsijPljXLafrlhAkEA7rlvfpD7smpFWBQRmK59HD4C0x8UcDrzn8+z1iRDxW2vZwqYrLc+pkkAMLy6hEepACjTrJvZ11aL8QFEwmjpDQJAWuhjb0F7BxKvves6oB2n4qvua7a5IrkXpsUloDWJH3C7Dfj5p6VHioZsB8FehtHEmdMPeU8QhONez+EZAVszwQJBAI9ns9N7MsgN0NRFUgC/KQbzNW0v6W41663f7q9AH7oU1t52Xhq7BZaMmeGtLfpStfITlHzHLsiOBAjl8zE6Jm0CQAENwuMcWcFmJaeVDTbuTuliiicBuD4rBdnz1iaXa8mhaehRljpsNiiLMDDMuEi5JoGKwmZ8OzbW4NN3NiBsO8M=-----END RSA PRIVATE KEY-----'
# 用来测试绑定的属性 就是上面输出的加密内容{cipher}前缀表示需要进行解密
test:test-name: '{cipher}AIDOSDRLvdEpXz3z+SeHKrZdWvXDkwy/JrXz/QpU7Z6VgtKKdEeMv8ElToOw7m1IcxJHi49bGBCCjjRCXli1KTn2bQbdnRJ0j7grr4xEhBVuSlgq7M3xVEfWgPvx/dIbvmqNNz2dr6tdHiZS9kiSgsdKW/3aRwWNBPwcbKpis3pB4lcW9+mbJghpH5I5XrtPRivZ4fjozVfn87m/XKZA2++K'

实现效果:在这里插入图片描述
这里使用其实是自己手动绑定配置类,但SpringCloud默认也会将Environment中的配置进行解密,通过DecryptEnvironmentPostProcessor(这个会在后续介绍),而不需要我们自己手动使用。
在这里插入图片描述
当我们禁用时,默认绑定是不会进行解密的。
在这里插入图片描述
在这里插入图片描述
TextEncryptorConfigBootstrapper更多只是暴露出来配置的加密器,供应用程序使用。

源码解析

@Overridepublic void initialize(BootstrapRegistry registry) {// 不存在TextEncryptor跳过if (!ClassUtils.isPresent("org.springframework.security.crypto.encrypt.TextEncryptor", null)) {return;}// 不存在KeyProperties时 注册KeyProperties到BootsrtapContext中 注入的是InstanceSupplier,用来延迟获取对象registry.registerIfAbsent(KeyProperties.class, context -> context.get(Binder.class).bind(KeyProperties.PREFIX, KeyProperties.class).orElseGet(KeyProperties::new));if (RSA_IS_PRESENT) {// 注册RSA的配置属性registry.registerIfAbsent(RsaProperties.class, context -> context.get(Binder.class).bind(RsaProperties.PREFIX, RsaProperties.class).orElseGet(RsaProperties::new));}// 注册TextEncryptor和TextEncryptorBindHandler TextEncryptor用于文本加密 TextEncryptorBindHandler用于使用Binder进行属性绑定时解密属性TextEncryptorUtils.register(registry);// promote beans to context// 添加BootsrapContext close监听器 将注册到BootsrapContext中的实例 注册到ApplicationContext中成为单例 供应用程序注入registry.addCloseListener(event -> {// 如果还是启用的2.4版本以前的Bootstrap加载的 这里就会跳过if (TextEncryptorUtils.isLegacyBootstrap(event.getApplicationContext().getEnvironment())) {return;}// 将KeyProperties和RsaProperties注册到BeanFactory中BootstrapContext bootstrapContext = event.getBootstrapContext();KeyProperties keyProperties = bootstrapContext.get(KeyProperties.class);ConfigurableListableBeanFactory beanFactory = event.getApplicationContext().getBeanFactory();if (keyProperties != null) {beanFactory.registerSingleton("keyProperties", keyProperties);}if (RSA_IS_PRESENT) {RsaProperties rsaProperties = bootstrapContext.get(RsaProperties.class);if (rsaProperties != null) {beanFactory.registerSingleton("rsaProperties", rsaProperties);}}// 注册TextEncryptor单例beanTextEncryptorUtils.promote(bootstrapContext, beanFactory);});}

TextEncryptorUtils

	public static void register(BootstrapRegistry registry) {// 注册TextEncryptorregistry.registerIfAbsent(TextEncryptor.class, context -> {KeyProperties keyProperties = context.get(KeyProperties.class);// KeyProperties中是否配置了key或者密钥文件locationif (TextEncryptorConfigBootstrapper.keysConfigured(keyProperties)) {if (TextEncryptorConfigBootstrapper.RSA_IS_PRESENT) {// 存在RsaSecretEncryptor 获取RsaProperties构建加密器RsaProperties rsaProperties = context.get(RsaProperties.class);// 创建加密器return createTextEncryptor(keyProperties, rsaProperties);}return new EncryptorFactory(keyProperties.getSalt()).create(keyProperties.getKey());}// 没有配置密钥的话 会默认注册一个不支持的文本加密器 使用加密和解密时抛出异常return new FailsafeTextEncryptor();});// 注册TextEncryptorBindHandlerregistry.registerIfAbsent(BindHandler.class, context -> {TextEncryptor textEncryptor = context.get(TextEncryptor.class);if (textEncryptor != null) {KeyProperties keyProperties = context.get(KeyProperties.class);return new TextEncryptorBindHandler(textEncryptor, keyProperties);}return null;});}public static void promote(BootstrapContext bootstrapContext, ConfigurableListableBeanFactory beanFactory) {// 将BootstrapContext中的文本加密器注册单例到BeanFactory中// 这里只注册了TextEncryptor 应用程序需要TextEncryptorBindHandler的话 可以通过BootstrapContext获取或者自己实现一个BootstrapRegistryInitializer 把他注入到BeanFactory中TextEncryptor textEncryptor = bootstrapContext.get(TextEncryptor.class);if (textEncryptor != null) {beanFactory.registerSingleton("textEncryptor", textEncryptor);}}public static TextEncryptor createTextEncryptor(KeyProperties keyProperties, RsaProperties rsaProperties) {KeyProperties.KeyStore keyStore = keyProperties.getKeyStore();if (keyStore.getLocation() != null) {if (keyStore.getLocation().exists()) {// 存在密钥文件时 构建Rsa密钥加密器 这个实现是随机生成Aes密钥 Aes密钥加密内容 Rsa公钥加密Aes密钥 将加密后密钥和Aes加密后类容一起Base64return new RsaSecretEncryptor(new KeyStoreKeyFactory(keyStore.getLocation(), keyStore.getPassword().toCharArray(),keyStore.getType()).getKeyPair(keyStore.getAlias(), keyStore.getSecret().toCharArray()),rsaProperties.getAlgorithm(), rsaProperties.getSalt(), rsaProperties.isStrong());}throw new IllegalStateException("Invalid keystore location");}// 使用密钥key创建文本加密器return new EncryptorFactory(keyProperties.getSalt()).create(keyProperties.getKey());}

EncryptorFactory

public TextEncryptor create(String data) {TextEncryptor encryptor;if (data.contains("RSA PRIVATE KEY")) {// 密钥key中包含RSA PRIVATE KEY 创建RsaSecretEncryptor(这个是pem文件格式中的Rsa私钥)encryptor = new RsaSecretEncryptor(data.replaceAll("\\n *", ""));}else if (data.startsWith("ssh-rsa") || data.contains("RSA PUBLIC KEY")) {throw new KeyFormatException();}else {// 返回16进制的Aes加密器encryptor = Encryptors.text(data, this.salt);}return encryptor;}

DefaultBootstrapContext的延迟加载机制

	// type需要获取实例的类型 exceptionSupplier获取不到抛出的异常@Overridepublic <T, X extends Throwable> T getOrElseThrow(Class<T> type, Supplier<? extends X> exceptionSupplier) throws X {synchronized (this.instanceSuppliers) {// 从注册的instanceSuppliers中获取指定类型的InstanceSupplierInstanceSupplier<?> instanceSupplier = this.instanceSuppliers.get(type);if (instanceSupplier == null) {throw exceptionSupplier.get();}return getInstance(type, instanceSupplier);}}@SuppressWarnings("unchecked")private <T> T getInstance(Class<T> type, InstanceSupplier<?> instanceSupplier) {// 先从单例池中获取T instance = (T) this.instances.get(type);if (instance == null) {// 不存在在获取对应实例instance = (T) instanceSupplier.get(this);if (instanceSupplier.getScope() == Scope.SINGLETON) {// 单例存放在单例池中this.instances.put(type, instance);}}// 返回对应实例return instance;}

延迟获取是为了在实例依赖的对象还没有初始化时,先注册一个InstanceSupplier。当实例依赖的对象创建完成时,在进行初始化。例如以上KeyProperties就是在Environment解析完成后进行的初始化,放在了BootstrapContext的close事件中,这时依赖的配置环境已经初始化完成。在这里插入图片描述

http://www.dtcms.com/a/602314.html

相关文章:

  • wordpress网站seo专业展馆展厅设计
  • LangGraph智能知识库系统架构设计方案 - 多agent架构
  • 在线C语言编译 | 提供便捷高效的在线编程环境
  • 二级网站建设费用网站有备案号吗
  • 搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
  • flutter项目老是卡在Running Gradle task ‘assembleRelease‘......
  • 东莞清溪镇做网站公司对网站有效的优化软件
  • Python的asyncio核心组件
  • 建立网站要多少钱销售平台有哪些
  • 诸暨公司做网站免费项目进度管理软件
  • leetcode:逆波兰表达式求值
  • sql中left join和inner join的区别
  • 最小栈--leetcode
  • 做网站的学什么代码wordpress 主题末班
  • 网站建设二公司psd转wordpress主题
  • 线性代数 - 3 阶方阵的行列式 可视化
  • 营销型网站首页模板做纺织生意用什么网站好
  • flink部署选型方案以及flink-on-k8s部署
  • 3GPP标准各个版本的介绍和演变
  • 网站设置的参数江西建设厅网站查询施工员
  • 程序员个人网站开发模板之家网页模板
  • 彭阳网站建设多少钱做网站怎么发展客户
  • 做软件项目的网站百度制作企业网站多少钱
  • 大型电商网站建设武平县网站建设
  • seo01网站营销推广软件有哪些
  • 建设银行网站信息补充网站建设app端
  • 结合 Leetcode 题探究KMP算法
  • Vue3 VueUse(组合式 API 工具库)
  • seo推广专员工作好做吗绍兴seo管理
  • 嵌入式开发中的 Git CI/CD