JMS 可用于在不同应用之间通讯,而应用系统内部对象之间的通讯可以使用 Spring Event 来实现(JMS 也能实现同样的效果)。
Spring Event 的关键对象为 事件
、事件发送者
和 事件监听器
:
- 事件类需要继承 ApplicationEvent
- 事件发送者需要实现接口 ApplicationEventPublisherAware,Spring 容器在创建事件发送者对象时因为发现它实现了接口 ApplicationEventPublisherAware,就会自动地注入 applicationEventPublisher,这个对象是真正的用于发送事件的对象
- 事件监听器需要实现接口 ApplicationListener,在 Spring 容器里注册事件监听器(其实就是生成一个对象,Spring 会自动识别它是否为事件监听器)
项目目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ├── main │ ├── java │ │ ├── Main.java │ │ └── com │ │ └── xtuer │ │ ├── bean │ │ │ └── User.java │ │ └── event │ │ ├── event │ │ │ └── UserEvent.java │ │ ├── listener │ │ │ └── UserEventListener.java │ │ └── publisher │ │ └── UserEventPublisher.java │ └── resources │ └── spring-beans.xml └── test ├── java └── resources
|
Gradle 依赖
有 ApplicationContext 实现的包就可以使用 Spring 事件,这里使用了 spring-webmvc
1 2 3
| compile 'org.springframework:spring-webmvc:4.3.0.RELEASE' compile 'org.projectlombok:lombok:1.16.10' compile 'com.alibaba:fastjson:1.2.17'
|
事件 UserEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.xtuer.event.event;
import com.xtuer.bean.User; import lombok.Getter; import lombok.Setter; import org.springframework.context.ApplicationEvent;
@Getter @Setter public class UserEvent extends ApplicationEvent { private String eventType; private User user;
public UserEvent(Object source, String eventType, User user) { super(source); this.eventType = eventType; this.user = user; } }
|
事件发送者 UserEventPublisher
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.xtuer.event.publisher;
import com.xtuer.bean.User; import com.xtuer.event.event.UserEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware;
public class UserEventPublisher implements ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher;
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; }
public void publish(User user, String action) { applicationEventPublisher.publishEvent(new UserEvent(this, action, user)); } }
|
事件监听器 UserEventListener
1 2 3 4 5 6 7 8 9 10 11
| package com.xtuer.event.listener;
import com.alibaba.fastjson.JSON; import com.xtuer.event.event.UserEvent; import org.springframework.context.ApplicationListener;
public class UserEventListener implements ApplicationListener<UserEvent> { public void onApplicationEvent(UserEvent event) { System.out.printf("Event received: %s - %s\n", event.getEventType(), JSON.toJSONString(event.getUser())); } }
|
User
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.xtuer.bean;
import lombok.Getter; import lombok.Setter;
@Getter @Setter public class User { private int id; private String username; private String password;
public User() { }
public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } }
|
Spring 配置文件
spring-beans.xml 注册事件发送者和监听器
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userEventPublisher" class="com.xtuer.event.publisher.UserEventPublisher"/>
<bean class="com.xtuer.event.listener.UserEventListener"/> </beans>
|
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import com.xtuer.bean.User; import com.xtuer.event.publisher.UserEventPublisher; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-beans.xml"); UserEventPublisher publisher = context.getBean("userEventPublisher", UserEventPublisher.class);
User user = new User(1, "Alice", "12345678"); publisher.publish(user, "CREATE_USER");
user.setPassword("Passw0rd"); publisher.publish(user, "UPDATE_USER"); } }
|
上面代码的逻辑为:
启动 Spring 容器
获取事件发送对象
发送消息
可以看到控制台里输出了下面的内容,说明事件 UserEvent 被事件监听器收到了:
1 2
| Event received: CREATE_USER - {"id":1,"password":"12345678","username":"Alice"} Event received: UPDATE_USER - {"id":1,"password":"Passw0rd","username":"Alice"}
|