`
234390216
  • 浏览: 10232902 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462622
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775515
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398352
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395022
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:679980
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:530892
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1183946
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:467908
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151384
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68148
社区版块
存档分类
最新评论

Spring(22)——ApplicationEvent

阅读更多

22 ApplicationEvent

Spring允许我们在ApplicationContext中发布ApplicationEvent事件,然后对应的ApplicationListener可以用来监听对应的事件。当发布了一个ApplicationEvent后,在对应bean容器中实现了ApplicationListener接口的bean实例都会接收到对应的通知,即对应的ApplicationListener回调方法将会被调用。

22.1内置事件

Spring自身已经为我们提供了几个ApplicationEvent,它们会由Spring在相应的时间自动进行发布,用户如果有需要可以对它们进行监听。具体来说有如下几种类型。

22.1.1 ContextRefreshedEvent

ContextRefreshedEvent将在对应的ApplicationContext调用refresh()方法时进行发布,这也包括直接使用配置文件等进行对应的ApplicationContext初始化时,因为在这个时候也会调用对应的refresh()方法。而在refresh()方法中是在该方法的最后才进行ContextRefreshedEvent发布的,也就是说在发布ContextRefreshedEvent时对应ApplicationContext中的bean定义都已经加载完成,对应的BeanFactoryPostProcessor都执行过了,需要实例化的bean也都已经实例化了。

22.1.2 ContextStartedEvent

ContextStartedEvent将在对应的ApplicationContext调用start()方法时进行发布。此时已经对所有实现了LifeCycle接口的bean回调了对应的start()方法。

22.1.3ContextStoppedEvent

ContextStoppedEvent将在对应的ApplicationContext调用stop()方法时进行发布。此时已经对所有实现了LifeCycle接口的bean回调了对应的stop()方法。

22.1.4ContextClosedEvent

ContextClosedEvent将在对应的ApplicationContext调用close()方法时进行发布。此时所有的资源都已经销毁了。ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent和ContextClosedEvent都继承自ApplicationContextEvent,因为它们都是针对ApplicationContext的事件。

22.1.5 ServletRequestHandledEvent

ServletRequestHandledEvent将在Spring处理了一个HttpRequest请求后进行发布,即对应的HttpRequest已经完成了。ServletRequestHandledEvent只能在使用DispatcherServlet时使用,当DispatcherServlet处理完一个HttpRequest请求后将发布一个ServletRequestHandledEvent。ServletRequestHandledEvent继承自RequestHandledEvent,所以当我们需要监听RequestHandledEvent时也可以监听ServletRequestHandledEvent。

22.2 自定义事件

Spring能够发布的事件是ApplicationEvent,其是一个继承了EventObject的抽象类。其源码如下所示,我们可以看到其只有一个构造方法,且必须传入一个对象作为当前事件发布的发布者。

public abstract class ApplicationEvent extends EventObject {

	/** use serialVersionUID from Spring 1.2 for interoperability */
	private static final long serialVersionUID = 7099057708183571937L;

	/** System time when the event happened */
	private final long timestamp;


	/**
	 * Create a new ApplicationEvent.
	 * @param source the component that published the event (never {@code null})
	 */
	public ApplicationEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
	}


	/**
	 * Return the system time in milliseconds when the event happened.
	 */
	public final long getTimestamp() {
		return this.timestamp;
	}

}

用户如果需要自定义事件则是自定义一个继承ApplicationEvent的类,除了提供构造父类必须要有的source对象以外,其它信息都可以由用户自定义。如下我们就简单的实现了一个自定义的ApplicationEvent,那么在之后进行事件发布时就可以使用自定义的MyApplicationEvent来作为ApplicationEvent进行发布了。

public class MyApplicationEvent extends ApplicationEvent {

	private static final long serialVersionUID = 1L;

	public MyApplicationEvent(Object source) {
		super(source);
	}

}

22.3 事件发布

事件的发布是由ApplicationEventPublisher接口中的publishEvent()方法定义的,其定义如下。

public interface ApplicationEventPublisher {

	void publishEvent(ApplicationEvent event);

}

ApplicationContext接口继承了ApplicationEventPublisher接口,所以我们可以直接使用ApplicationContext来进行事件的发布。如下示例中我们就给Hello注入了一个ApplicationContext,然后在调用其doSomething()方法时通过注入的ApplicationContext发布了一个自定义的MyApplicationEvent。

@Component
public class Hello {

	@Autowired
	private ApplicationContext context;
	
	public void doSomething() {
		System.out.println("----do something....");
		//发布一个自定义的MyApplicationEvent
		context.publishEvent(new MyApplicationEvent(this));
	}

}

除了直接使用ApplicationContext进行事件发布外,Spring还给我们提供了一个用于发布事件的ApplicationEventPublisher接口对应的Aware接口——ApplicationEventPublisherAware,该接口跟Spring提供的其它Aware接口一样,当一个bean实现了该接口以后,Spring在实例化对应的bean后将调用其中的回调方法以传入一个ApplicationEventPublisher,通常就是传递的当前的ApplicationContext对象。所以我们还可以让我们的bean实现ApplicationEventPublisherAware接口,然后使用Spring传入的ApplicationEventPublisher发布对应的事件。所以上述示例我们也可以把它改成实现ApplicationEventPublisherAware的方式,示例如下。

@Component
public class Hello implements ApplicationEventPublisherAware {

	private ApplicationEventPublisher eventPublisher;
	
	public void doSomething() {
		System.out.println("----do something....");
		//发布一个自定义的MyApplicationEvent
		this.eventPublisher.publishEvent(new MyApplicationEvent(this));
	}

	public void setApplicationEventPublisher(
			ApplicationEventPublisher applicationEventPublisher) {
		this.eventPublisher = applicationEventPublisher;
	}

}

22.4 事件监听

事件监听需要定义对应的监听器,Spring中用于监听ApplicationEvent的监听器是通过ApplicationListener来定义的。ApplicationListener是一个接口,其定义如下,我们可以看到该接口中使用了泛型,即可以指定只监听某种类型的ApplicationEvent。

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	void onApplicationEvent(E event);

}

ApplicationListener每次监听到对应的ApplicationEvent后都将调用其onApplicationEvent()方法。所以如果我们想定义一个只监听之前自定义的MyApplicationEvent的监听器,则可以如下定义,如果想监听所有的ApplicationEvent,则可以将泛型指定为ApplicationEvent,即将如下的MyApplicationEvent改成ApplicationEvent。

public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {

	public void onApplicationEvent(MyApplicationEvent event) {
		System.out.println(event.getSource() + "****************" + event.getTimestamp());;
	}

}

光实现了ApplicationListener接口,对应的监听器还监听不到对应的事件。我们需要把它们定义bean容器中的一个bean,这样当Spring发布了一个事件后就会将其传递给相匹配的监听器。所以针对于上述监听器,我们可以在基于XML进行配置时在对应的XML配置文件中进行如下配置。

<bean class="com.app.MyApplicationListener"/>

如果是基于注解的扫描则可以在MyApplicationListener上使用@Component等注解进行标注。

(注:本文是基于Spring4.1.0所写)

 

0
0
分享到:
评论

相关推荐

    Spring特性——事件驱动模型

    本篇文章将深入探讨Spring框架的一个重要特性——事件驱动模型。通过理解这一特性,开发者可以更好地利用Spring来实现应用间的通信和协调,提高系统的灵活性和可扩展性。 事件驱动模型是一种设计模式,它基于发布/...

    二、Spring源码分析——BeanFactory

    《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...

    222-手把手带你写一个MiniSpring

    "222-手把手带你写一个MiniSpring"这个主题,旨在通过实践教学的方式,让你了解并掌握Spring框架的基本原理,从而能够自己动手实现一个简化版的Spring框架——MiniSpring。 【描述】"222-手把手带你写一个Mini...

    Spring5 源码分析(第 2 版)-某Tom老师

    首先,我们要了解Spring框架的核心组件——依赖注入(Dependency Injection,简称DI)。在Spring5中,DI仍然是核心设计模式,它使得对象之间的依赖关系得以解耦,增强了代码的可测试性和可维护性。Tom老师的文档会...

    spring3.1.2源码包

    5. **事件驱动**:Spring的ApplicationEvent和ApplicationListener机制,如何在容器内实现事件发布和监听。 四、源码学习价值 理解Spring的源码,可以帮助我们: 1. 掌握Spring的工作原理,优化代码设计。 2. ...

    Spring_2900_Registration_7

    本文将深入探讨Spring框架中的一个重要组件——注册(Registration),以及它与Spring_2900_Registration_7相关的知识。 首先,我们要明白Spring框架的核心理念是依赖注入(Dependency Injection,简称DI)。通过DI...

    Spring的经典面试题

    - **Spring IoC容器**:Spring的IoC容器主要由两个包组成——`org.springframework.beans`和`org.springframework.context`。其中`org.springframework.beans`主要提供Bean操作的基本支持,而`org.springframework....

    spring-beans

    综上,`spring-beans`模块是Spring框架的基石,它的设计和实现体现了Spring的核心理念——简化企业级应用开发,通过依赖注入和面向切面编程等机制,提高了代码的可测试性和可维护性。掌握`spring-beans`的使用,对于...

    spring基本原理的小实验,可供初学者学习使用

    首先,让我们从Spring的核心概念——依赖注入开始。依赖注入是Spring框架的灵魂,它允许我们解耦组件间的依赖关系,使得代码更加灵活,易于测试和维护。在项目中,你可能会看到如何使用XML配置文件或注解(如@...

    tiny-spring-step-6-invite-application-context.zip

    本篇文章将深入探讨Spring框架的核心组件——Inversion of Control(IoC)容器,特别是ApplicationContext的引入及其在实际应用中的重要性。 一、IoC容器的概念与作用 IoC,即“控制反转”,是Spring框架的核心...

    spring-core.

    Spring框架作为Java领域中最为重要的应用框架之一,其核心模块——Spring Core,扮演着至关重要的角色。Spring Core是Spring框架的基础,它提供了许多基础功能和服务,使得开发人员能够构建出松散耦合、可测试且易于...

    Spring源码解析文件说明

    - 早期事件记录:创建一个`LinkedHashSet&lt;ApplicationEvent&gt;`来存储一些早期发生的事件。 #### 2. 获取或创建BeanFactory - `obtainFreshBeanFactory()` 接下来,系统会进入获取或创建`BeanFactory`的阶段,具体...

    spring中监听事件

    Spring还提供了一种类型安全的事件监听方式——`ApplicationEventMulticaster`。这个接口允许注册监听器并广播事件,同时提供了更多的控制,如异步事件处理、事件广播策略等。`SimpleApplicationEventMulticaster`是...

    Java模拟的spring实现

    首先,让我们来看看Spring的核心概念——依赖注入(Dependency Injection,简称DI)。依赖注入是将对象之间的依赖关系交给容器管理,而不是由对象自身负责。在模拟实现中,我们可以创建一个类`BeanFactory`,它负责...

    spring源码包-源码包源码包

    8. **AOP 代理**:Spring 使用两种代理模式——JDK 动态代理和 CGLIB 代理,根据目标类是否实现了接口来选择。源码中,`AbstractAutoProxyCreator` 负责创建代理对象。 9. **事件驱动架构**:Spring 支持事件发布和...

    myspring.rar

    在IT领域,Spring框架无疑是Java企业级应用开发的首选,其中的核心组件——控制反转(Inversion of Control,简称IOC)容器,更是开发者们广泛讨论和使用的焦点。本篇文章将深入探讨“手写Spring IOC”的相关知识,...

    spring-core

    Spring框架作为Java领域最流行的开源框架之一,其核心模块——Spring Core,是整个框架的基础,提供了许多关键功能。本文将深入探讨Spring Core的主要内容,包括依赖注入(Dependency Injection,DI)、资源管理、...

    spring-framework:springcore项目

    Spring Framework作为Java领域最广泛使用的开源框架之一,其核心模块——Spring Core,是整个框架的基础。Spring Core提供了依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect-Oriented Programming...

    观察者模式

    9. **扩展**:除了Java内置的`Observer`和`Observable`,开发者还可以使用第三方库如Guava的`EventBus`,或者Spring框架的`ApplicationEvent`和`ApplicationListener`,这些都提供了更高级的观察者模式实现。...

Global site tag (gtag.js) - Google Analytics