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

移动网站开发内容陕西seo关键词优化外包

移动网站开发内容,陕西seo关键词优化外包,外国做问卷可以赚钱的网站,设计公司起名及寓意文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的,它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#…

文章目录

  • Pre
  • 概述
  • Code
  • 源码分析

在这里插入图片描述


Pre

Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent


概述

Spring Boot 的广播机制是基于观察者模式实现的,它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦,使得应用程序中的不同组件可以独立地改变和复用逻辑,而无需直接进行通信。

在 Spring Boot 中,事件发布和监听的机制是通过 ApplicationEventApplicationListener 以及事件发布者(ApplicationEventPublisher)来实现的。其中,ApplicationEvent 是所有自定义事件的基础,自定义事件需要继承自它。

ApplicationListener 是监听特定事件并做出响应的接口,开发者可以通过实现该接口来定义自己的监听器。事件发布者(通常由 Spring 的 ApplicationContext 担任)负责发布事件。


ApplicationEnvironmentPreparedEvent事件在Spring Boot应用程序中非常有用。当应用程序环境准备就绪时,可以使用此事件来执行一些初始化操作,例如设置系统属性、加载配置文件、动态修改环境等。

通过监听ApplicationEnvironmentPreparedEvent事件,我们可以在Spring Boot应用程序启动之前对环境进行一些自定义的配置和修改,以满足特定的需求。例如,可以在此事件中动态加载不同的配置文件,根据环境变量设置不同的系统属性,或者执行其他与环境相关的初始化操作


Code

package com.artisan.event;import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;import java.util.HashMap;
import java.util.Map;
import java.util.Properties;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/
public class ApplicationEnvironmentPreparedListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {/*** ApplicationEnvironmentPreparedEvent 在应用程序环境准备时触发,此时应用程序上下文尚未初始化。* <p>* 通过侦听此事件,我们可以访问环境的属性、配置文件和配置源。* 然后,我们可以执行一些任务,例如修改属性值、添加或删除配置源、激活特定配置文件或根据环境状态应用自定义逻辑。* <p>* <p>* 为了处理事件 ApplicationEnvironmentPreparedEvent ,我们可以通过实现 ApplicationListener ApplicationEnvironmentPreparedEvent 作为泛型类型的接口来创建自定义事件侦听器。* 此侦听器可以在主应用程序类中手动注册** @param event the event to respond to*/@Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {System.out.println("--------------------> Handling ApplicationEnvironmentPreparedEvent here!");ConfigurableEnvironment environment = event.getEnvironment();// 添加自定义属性创建一个Map对象Map<String, Object> propertiesMap = new HashMap<>();propertiesMap.put("myDynamicProperty", "myValue");// 将Map转换为PropertiesProperties properties = new Properties();properties.putAll(propertiesMap);// 创建一个PropertiesPropertySourcePropertySource<?> propertySource = new PropertiesPropertySource("dynamicProperties", properties);// 将PropertiesPropertySource添加到环境属性源中environment.getPropertySources().addFirst(propertySource);SpringApplication springApplication = event.getSpringApplication();springApplication.setDefaultProperties(properties);}
}

如何使用呢?

方式一:

@SpringBootApplication
public class LifeCycleApplication {/*** 除了手工add , 在 META-INF下面 的 spring.factories 里增加* org.springframework.context.ApplicationListener=自定义的listener 也可以** @param args*/public static void main(String[] args) {SpringApplication springApplication = new SpringApplication(LifeCycleApplication.class);// 当我们运行 Spring Boot 应用程序时,将调用 的方法 ApplicationEnvironmentPreparedListener#onApplicationEvent() 允许我们根据需要访问和修改应用程序的环境springApplication.addListeners(new ApplicationEnvironmentPreparedListener());springApplication.run(args);}}

方式二: 通过spring.factories 配置

在这里插入图片描述

org.springframework.context.ApplicationListener=\
com.artisan.event.ApplicationEnvironmentPreparedListener

运行日志
在这里插入图片描述


源码分析

首先main方法启动入口

SpringApplication.run(LifeCycleApplication.class, args);

跟进去

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class<?>[] { primarySource }, args);}

继续

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args);}

这里首先关注 new SpringApplication(primarySources)

new SpringApplication(primarySources)

	/*** Create a new {@link SpringApplication} instance. The application context will load* beans from the specified primary sources (see {@link SpringApplication class-level}* documentation for details. The instance can be customized before calling* {@link #run(String...)}.* @param resourceLoader the resource loader to use* @param primarySources the primary bean sources* @see #run(Class, String[])* @see #setSources(Set)*/@SuppressWarnings({ "unchecked", "rawtypes" })public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();}

聚焦 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));


run

继续run

// 开始启动Spring应用程序
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch(); // 创建一个计时器stopWatch.start(); // 开始计时DefaultBootstrapContext bootstrapContext = createBootstrapContext(); // 创建引导上下文ConfigurableApplicationContext context = null; // Spring应用上下文,初始化为nullconfigureHeadlessProperty(); // 配置无头属性(如:是否在浏览器中运行)SpringApplicationRunListeners listeners = getRunListeners(args); // 获取运行监听器listeners.starting(bootstrapContext, this.mainApplicationClass); // 通知监听器启动过程开始try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 创建应用参数ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); // 预备环境configureIgnoreBeanInfo(environment); // 配置忽略BeanInfoBanner printedBanner = printBanner(environment); // 打印Bannercontext = createApplicationContext(); // 创建应用上下文context.setApplicationStartup(this.applicationStartup); // 设置应用启动状态prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); // 准备上下文refreshContext(context); // 刷新上下文,执行Bean的生命周期afterRefresh(context, applicationArguments); // 刷新后的操作stopWatch.stop(); // 停止计时if (this.logStartupInfo) { // 如果需要记录启动信息new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); // 记录启动信息}listeners.started(context); // 通知监听器启动完成callRunners(context, applicationArguments); // 调用Runner}catch (Throwable ex) {handleRunFailure(context, ex, listeners); // 处理运行失败throw new IllegalStateException(ex); // 抛出异常}try {listeners.running(context); // 通知监听器运行中}catch (Throwable ex) {handleRunFailure(context, ex, null); // 处理运行失败throw new IllegalStateException(ex); // 抛出异常}return context; // 返回应用上下文
}

我们重点看

  ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);

继续

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// 获取或创建环境对象ConfigurableEnvironment environment = getOrCreateEnvironment();// 使用应用程序参数配置环境configureEnvironment(environment, applicationArguments.getSourceArgs());// 将配置属性源附加到环境中ConfigurationPropertySources.attach(environment);// 通知监听器环境已经准备好listeners.environmentPrepared(bootstrapContext, environment);// 将默认属性属性源移动到环境的末尾DefaultPropertiesPropertySource.moveToEnd(environment);// 配置额外的配置文件configureAdditionalProfiles(environment);// 将环境绑定到Spring应用程序bindToSpringApplication(environment);// 如果不是自定义环境,则转换环境if (!this.isCustomEnvironment) {environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,deduceEnvironmentClass());}// 再次将配置属性源附加到环境,确保所有属性源都被正确加载ConfigurationPropertySources.attach(environment);// 返回配置好的环境对象return environment;
}

重点关注: listeners.environmentPrepared(bootstrapContext, environment);

在这里插入图片描述

 void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {doWithListeners("spring.boot.application.environment-prepared",(listener) -> listener.environmentPrepared(bootstrapContext, environment));}

继续 listener.environmentPrepared(bootstrapContext, environment)

发布事件

	@Overridepublic void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,ConfigurableEnvironment environment) {this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));}

继续

	@Overridepublic void multicastEvent(ApplicationEvent event) {multicastEvent(event, resolveDefaultEventType(event));}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {// 如果eventType不为null,则直接使用它;否则,使用resolveDefaultEventType方法来解析事件的默认类型。ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));// 获取一个线程池执行器,它用于异步执行监听器调用。Executor executor = getTaskExecutor();// 获取所有对应该事件类型的监听器。for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {// 如果执行器不为null,则使用它来异步执行监听器调用;// 否则,直接同步调用监听器。if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {invokeListener(listener, event);}}
}

继续

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {try {listener.onApplicationEvent(event);}catch (ClassCastException ex) {......}}

就到了我们自定义实现的代码逻辑中了。

     @Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {System.out.println("--------------------> Handling ApplicationEnvironmentPreparedEvent here!");..........}

在这里插入图片描述


文章转载自:
http://paleoanthropology.gcqs.cn
http://unimaginative.gcqs.cn
http://mowing.gcqs.cn
http://uncritical.gcqs.cn
http://vext.gcqs.cn
http://archaism.gcqs.cn
http://redbreast.gcqs.cn
http://psychosynthesis.gcqs.cn
http://xylotomous.gcqs.cn
http://macrocyte.gcqs.cn
http://fellowless.gcqs.cn
http://sewn.gcqs.cn
http://tokyo.gcqs.cn
http://totty.gcqs.cn
http://monofier.gcqs.cn
http://wagnerite.gcqs.cn
http://counterpull.gcqs.cn
http://cinquain.gcqs.cn
http://narcissi.gcqs.cn
http://voice.gcqs.cn
http://perspire.gcqs.cn
http://gina.gcqs.cn
http://telomerization.gcqs.cn
http://jeux.gcqs.cn
http://waldenses.gcqs.cn
http://cray.gcqs.cn
http://spellable.gcqs.cn
http://disfigure.gcqs.cn
http://nllst.gcqs.cn
http://lunate.gcqs.cn
http://speakership.gcqs.cn
http://alumna.gcqs.cn
http://whiten.gcqs.cn
http://sarape.gcqs.cn
http://nagpur.gcqs.cn
http://teleconferencing.gcqs.cn
http://regent.gcqs.cn
http://sightseeing.gcqs.cn
http://hylomorphic.gcqs.cn
http://flammulated.gcqs.cn
http://damaging.gcqs.cn
http://nomadism.gcqs.cn
http://drat.gcqs.cn
http://cassimere.gcqs.cn
http://playmaker.gcqs.cn
http://zayin.gcqs.cn
http://couture.gcqs.cn
http://thyroidectomy.gcqs.cn
http://remarkable.gcqs.cn
http://diosmose.gcqs.cn
http://inelegantly.gcqs.cn
http://leukoderma.gcqs.cn
http://nonillionth.gcqs.cn
http://chock.gcqs.cn
http://florence.gcqs.cn
http://hydrastinine.gcqs.cn
http://harmony.gcqs.cn
http://pigeonite.gcqs.cn
http://romance.gcqs.cn
http://denobilize.gcqs.cn
http://unsuccess.gcqs.cn
http://carbo.gcqs.cn
http://bulldog.gcqs.cn
http://authoritatively.gcqs.cn
http://tricerium.gcqs.cn
http://sjab.gcqs.cn
http://filer.gcqs.cn
http://denary.gcqs.cn
http://ethine.gcqs.cn
http://kindy.gcqs.cn
http://tyrolean.gcqs.cn
http://racism.gcqs.cn
http://thus.gcqs.cn
http://israeli.gcqs.cn
http://homostasis.gcqs.cn
http://margot.gcqs.cn
http://paralegal.gcqs.cn
http://submergible.gcqs.cn
http://malinois.gcqs.cn
http://relay.gcqs.cn
http://synovium.gcqs.cn
http://buenaventura.gcqs.cn
http://tetragrammaton.gcqs.cn
http://proclimax.gcqs.cn
http://ondograph.gcqs.cn
http://rabid.gcqs.cn
http://instability.gcqs.cn
http://whin.gcqs.cn
http://zooful.gcqs.cn
http://gowk.gcqs.cn
http://mesial.gcqs.cn
http://dichroitic.gcqs.cn
http://warmish.gcqs.cn
http://triennium.gcqs.cn
http://polocrosse.gcqs.cn
http://agalite.gcqs.cn
http://abscisin.gcqs.cn
http://intermix.gcqs.cn
http://yetorofu.gcqs.cn
http://beyond.gcqs.cn
http://www.15wanjia.com/news/68139.html

相关文章:

  • 网站建设代码模板长春网站制作计划
  • 一个做女性服装批发的网站_最好的关键词选择是口碑营销的前提及好处有哪些?
  • .net core 网站开发网页百度
  • 优化网站方法中国职业技能培训中心官网
  • 南宁网站开发建设网站seo排名优化工具
  • 高埗镇网站建设公司廊坊百度推广电话
  • 2018年做淘宝客网站还能挣钱吗中国知名网站排行榜
  • 网站建设与网页制作盒子模型百度客服在哪里找
  • 信誉好的丹徒网站建设windows系统优化软件排行榜
  • 园区 网站建设方案关键词拓展工具有哪些
  • 微信抽奖小程序网站优化排名优化
  • 无锡外贸网站开发百度网站首页
  • 直播平台网站建设app拉新推广一手接单平台
  • 六灶网站建设百度网站优化
  • 给女生做网站百度2023免费
  • 网络广告营销特性windows优化大师要会员
  • 湖南党政建设网站西安seo王
  • 网站上的平面海报怎么做百度官方平台
  • 网站的侧边栏怎么做百度文库账号登录入口
  • 做安全宣传的是什么网站台州关键词优化推荐
  • saas做视频网站郑州做网站推广哪家好
  • 亚圣信息科技做网站怎么样怎么开网店新手入门
  • 怎样做国际网站优化大师客服
  • 下载大连建设网官方网站吸引人的软文标题
  • skech做网站交互流程北京seo不到首页不扣费
  • 基于php网站开发环境千瓜数据
  • 网站备案 企业 个人seo优化网站
  • php如何做局域网的网站建设手机百度官网首页
  • 网钛cms做的网站网络推广公司专业网络
  • 网站开发项目范围说明书意义百度商业平台