Skip to content

События в Spring

Синопсис

События в спринге реализуются очень просто. Любой бин может прослушивать события если он реализует интерфейс ApplicationListener. Само событие это класс производный от ApplicationEvent а сам этот класс не обязан быть бином. Публикуются события с помощью метода publishEvent() класса реализующего интерфейс ApplicationEventPublisher который наследует интерфейс ApplicationContext.

Готовый проект можно взять с gitHub: https://github.com/dev-blogs/spring подпроект event-handler

Структура проекта

event-handler
    ├──src
    │   ├─main
    │   │   └─java
    │   │       └─com
    │   │           └─devblogs
    │   │               └─event
    │   │                   ├─App.java
    │   │                   ├─MessageEvent.java
    │   │                   ├─MessageEventListener.java
    │   │                   ├─Publisher.java
    │   │                   └─StartEventHandler.java
    │   └─resources
    │       └─context.xml
    └──pom.xml

MessageEvent — класс события:

MessageEvent.java

package com.devblogs.event;

import org.springframework.context.ApplicationEvent;

public class MessageEvent extends ApplicationEvent {
	private String msg;
	
	public MessageEvent(Object source, String msg) {
		super(source);
		this.msg = msg;
	}
	
	public String getMessage() {
		return msg;
	}
}

MessageEventListener — класс слушатель. Классом слушателем может стать любой класс который А) является бином, Б) реализует интерфейс ApplicationListener. Когда выполняются два этих условия, ApplicationContext автоматически регистрирует его как бин-слушатель. В нашем примере, класс MessageEventListener заинтересован только в событиях MessageEvent так как он реализует типизированный интерфейс ApplicationListener:

MessageEventListener.java

package com.devblogs.event;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

@Service
public class MessageEventListener implements ApplicationListener<MessageEvent> {
	public void onApplicationEvent(MessageEvent event) {
		MessageEvent msgEvt = (MessageEvent) event;
		System.out.println("Received: " + msgEvt.getMessage());
	}
}

Публикация события. Для того чтобы опубликовать событие, нужно создать экземпляр класса события и передать его методу publishEvent класса реализующего интерфейс ApplicationEventPublisher которым является класс ApplicationContext:

Publisher.java

package com.devblogs.event;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class Publisher implements ApplicationContextAware {
	private ApplicationContext context;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.context = applicationContext;
	}
	
	public void publish(String message) {
		context.publishEvent(new MessageEvent(this, message));
	}
}

Класс StartEventHandler является слушателем события ContextRefreshedEvent которое публикуется самим спрингом после того как контекст спринга был сформирован. В этот класс инжектится объект Publisher который был определён выше, после того как слушатель словит события о том, что спринг сконфигурирован и готов к работе, класс StartEventHandler, в свою очередь, публикует два события MessageEvent с сообщениями test message1 и :

StartEventHandler.java

package com.devblogs.event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

@Service
public class StartEventHandler implements ApplicationListener<ContextRefreshedEvent> {
	@Autowired
	private Publisher publisher;
	
	public void onApplicationEvent(ContextRefreshedEvent event) {
		System.out.println("StartEventHandler listener");
		publisher.publish("test message1");
		publisher.publish("test message2");
	}
}

Класс энтерпоинт или класс запуска приложения:

App.java

package com.devblogs.event;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
	public static void main(String[] args) {
		new ClassPathXmlApplicationContext("classpath:context.xml");
	}
}

Конфигурация

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
    <context:component-scan base-package="com.devblogs.event"/>
    
</beans>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.devblogs</groupId>
	<artifactId>event-handler</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>event-handler</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>3.2.7.RELEASE</spring.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

Сборка и запуск

Для запуска примера запустим на выполнение файл com.devblogs.event.App или соберем проект в джарник и запустим джарник (как это делается описывается в этом посте:

StartEventHandler listener
Received: test message1
Received: test message2

Поделиться в социальных сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники
Опубликовать в Яндекс

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *