栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ApplicationListener机制(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ApplicationListener机制(一)

ApplicationListener机制

ApplicationListener机制是Sprint提供的用于实现发布订阅功能的机制,也是观察者模式的典型实现。程序中事先注册ApplicationListener,当某些事件发生的时候通过调用ApplicationListener#onApplicationEvent就可以实现发布订阅功能。

public interface ApplicationListener extends EventListener {

	
	void onApplicationEvent(E event);
}
public abstract class ApplicationEvent extends EventObject {

	
	private static final long serialVersionUID = 7099057708183571937L;

	
	private final long timestamp;


	
	public ApplicationEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
	}


	
	public final long getTimestamp() {
		return this.timestamp;
	}

}

在这个过程中发送器就很重要了,相当于一个中转站,而在Spring中完成这个功能的类是:SimpleApplicationEventMulticaster,他通过线程池技术实现了同步和异步执行两种方式。
该类实现了ApplicationEventMulticaster,提供注册监听器ApplicationListener和广播事件的方法multicastEvent,multicastEvent方法中从BeanFactory中获取ApplicationListener进行调用。

public interface ApplicationEventMulticaster {

	
	void addApplicationListener(ApplicationListener listener);

	
	void addApplicationListenerBean(String listenerBeanName);

	
	void removeApplicationListener(ApplicationListener listener);

	
	void removeApplicationListenerBean(String listenerBeanName);

	
	void removeAllListeners();

	
	void multicastEvent(ApplicationEvent event);

	
	void multicastEvent(ApplicationEvent event, ResolvableType eventType);

}
SimpleApplicationEventMulticaster在什么地方初始化和使用?

在Spring的ApplicationContext的refresh方法中对ApplicationEventMulticaster进行了初始化

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}

如果我们没有自定义ApplicationEventMulticaster,那么系统就使用默认的SimpleApplicationEventMulticaster。
ApplicationEventPublisher 提供了发送事件的方法,而ApplicationContext继承自此接口,所以我们在应用中通过ApplicationContext#publishEvent方法即可发布事件。

public interface ApplicationEventPublisher {

	
	void publishEvent(ApplicationEvent event);

	
	void publishEvent(Object event);

}
	protected void publishEvent(Object event, ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Publishing event in " + getDisplayName() + ": " + event);
		}

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent(this, event);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}
 
SpringBoot中对ApplicationListener机制的使用 
public interface SpringApplicationRunListener {

	
	void starting();

	
	void environmentPrepared(ConfigurableEnvironment environment);

	
	void contextPrepared(ConfigurableApplicationContext context);

	
	void contextLoaded(ConfigurableApplicationContext context);

	
	void finished(ConfigurableApplicationContext context, Throwable exception);

}

SpringApplicationRunListener定义了应用运行各个时机的方法,其实现类EventPublishingRunListener使用的广播器就是SimpleApplicationEventMulticaster,他的ApplicationListener来自SpringApplication初始化中通过spring.factories机制获取的。EventPublishingRunListener也是采用spring.factories机制注册。然后在SpringApplication中获取,再通过SpringApplicationRunListeners包装

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

	private final SpringApplication application;

	private final String[] args;

	private final SimpleApplicationEventMulticaster initialMulticaster;

	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
	private void initialize(Object[] sources) {
		if (sources != null && sources.length > 0) {
			this.sources.addAll(Arrays.asList(sources));
		}
		this.webEnvironment = deduceWebEnvironment();
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}
	
	private SpringApplicationRunListeners getRunListeners(String[] args) {
		Class[] types = new Class[] { SpringApplication.class, String[].class };
		return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
				SpringApplicationRunListener.class, types, this, args));
	}

然后在各个时机进行调用

	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号