mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add event
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
/**
|
||||
* 事件接口,所有事件必须实现此接口
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public interface Event{
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
/**
|
||||
* 事件发布者接口,用于发布事件
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public interface EventPublisher {
|
||||
|
||||
/**
|
||||
* 注册订阅者,订阅者将接收到所有发布者发布的事件
|
||||
*
|
||||
* @param subscriber 订阅者
|
||||
* @return this
|
||||
*/
|
||||
EventPublisher register(Subscriber subscriber);
|
||||
|
||||
/**
|
||||
* 发布事件,事件发布者将事件发布给所有订阅者
|
||||
*
|
||||
* @param event 事件对象
|
||||
*/
|
||||
void publish(Event event);
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.lang.loader.LazyFunLoader;
|
||||
import org.dromara.hutool.core.lang.loader.Loader;
|
||||
import org.dromara.hutool.core.thread.ThreadUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
/**
|
||||
* 简单的事件发布者实现,基于{@link Subscriber}和{@link Event}实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class SimpleEventPublisher implements EventPublisher {
|
||||
|
||||
/**
|
||||
* 创建一个默认的{@code SimpleEventPublisher},默认线程池为{@link ThreadUtil#newExecutor()}
|
||||
*
|
||||
* @return {@code SimpleEventPublisher}
|
||||
*/
|
||||
public static SimpleEventPublisher of() {
|
||||
return of(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个默认的{@code SimpleEventPublisher},默认线程池为{@link ThreadUtil#newExecutor()}
|
||||
*
|
||||
* @param subscribers 订阅者列表,也可以传入空列表后调用{@link #register(Subscriber)}添加
|
||||
* @return {@code SimpleEventPublisher}
|
||||
*/
|
||||
public static SimpleEventPublisher of(final List<Subscriber> subscribers) {
|
||||
return new SimpleEventPublisher(subscribers, null);
|
||||
}
|
||||
|
||||
private final List<Subscriber> subscribers;
|
||||
private Loader<ExecutorService> executorServiceLoader;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param subscribers 订阅者列表
|
||||
* @param executorServiceLoader 线程池加载器,用于异步执行,默认为{@link ThreadUtil#newExecutor()}
|
||||
*/
|
||||
public SimpleEventPublisher(final List<Subscriber> subscribers, final Loader<ExecutorService> executorServiceLoader) {
|
||||
this.subscribers = ObjUtil.defaultIfNull(subscribers, ArrayList::new);
|
||||
this.executorServiceLoader = ObjUtil.defaultIfNull(executorServiceLoader, LazyFunLoader.of(ThreadUtil::newExecutor));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自定义的{@link ExecutorService}线程池,默认为{@link ThreadUtil#newExecutor()}
|
||||
*
|
||||
* @param executorService {@link ExecutorService},不能为空
|
||||
* @return this
|
||||
*/
|
||||
public SimpleEventPublisher setExecutorService(final ExecutorService executorService) {
|
||||
this.executorServiceLoader = () -> Assert.notNull(executorService);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventPublisher register(final Subscriber subscriber) {
|
||||
subscribers.add(subscriber);
|
||||
Collections.sort(subscribers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publish(final Event event) {
|
||||
for (final Subscriber subscriber : subscribers) {
|
||||
if (subscriber.async()) {
|
||||
executorServiceLoader.get().submit(() -> subscriber.update(event));
|
||||
} else {
|
||||
subscriber.update(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* 基于事件源的事件实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class SourceEvent extends EventObject implements Event {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param source 事件源
|
||||
*/
|
||||
public SourceEvent(final Object source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
import org.dromara.hutool.core.comparator.CompareUtil;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* 订阅者接口
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public interface Subscriber extends EventListener, Comparable<Subscriber> {
|
||||
|
||||
/**
|
||||
* 当事件发生时的操作
|
||||
*
|
||||
* @param event 事件对象,根据不同事件,可选是否执行
|
||||
*/
|
||||
void update(Event event);
|
||||
|
||||
/**
|
||||
* 获取事件执行顺序,值越小越先执行
|
||||
*
|
||||
* @return 执行顺序
|
||||
*/
|
||||
default int order() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int compareTo(final Subscriber o) {
|
||||
return CompareUtil.compare(this.order(), o.order());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否异步执行,默认为false,同步执行
|
||||
*
|
||||
* @return 是否异步执行
|
||||
*/
|
||||
default boolean async() {
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 发布订阅模式封装,发布/订阅是一种消息范式<br>
|
||||
* 消息的发送者(EventPublisher)将事件或消息(Event)广播出去,订阅者(Subscriber)接收到消息后处理。<br>
|
||||
* Hutool中的事件或消息(Event)是一个无方法接口,可以通过实现此接口灵活的定义不同消息类型。<br>
|
||||
* 消息的发送者(EventPublisher)可以通过register方法注册订阅者,调用publish发布消息
|
||||
*
|
||||
* <pre>{@code
|
||||
* publish /----->Subscriber
|
||||
* Event -------- EventPublisher- ----->Subscriber
|
||||
* \----->Subscriber
|
||||
* }</pre>
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
package org.dromara.hutool.core.lang.event;
|
@@ -0,0 +1,35 @@
|
||||
package org.dromara.hutool.core.lang.event;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SimpleEventPublisherTest {
|
||||
|
||||
@Test
|
||||
void registerTest() {
|
||||
final SimpleEventPublisher publisher = SimpleEventPublisher.of();
|
||||
publisher.register(event -> Assertions.assertEquals("test", ((TestEvent)event).getName()));
|
||||
|
||||
publisher.publish(new TestEvent("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceEventTest() {
|
||||
final SimpleEventPublisher publisher = SimpleEventPublisher.of();
|
||||
publisher.register(event -> Assertions.assertEquals("test", ((SourceEvent)event).getSource()));
|
||||
|
||||
publisher.publish(new SourceEvent("test"));
|
||||
}
|
||||
|
||||
private static class TestEvent implements Event {
|
||||
private final String name;
|
||||
|
||||
public TestEvent(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user