mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-10-14 10:19:04 +00:00
init project
This commit is contained in:
1 parent
b7f28da485
commit
bce060a28e
573 files changed
+84513
No files matched your search
+244
@@ -0,0 +1,244 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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.zfoo</groupId>
|
||||
<artifactId>event</artifactId>
|
||||
<version>3.0</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
<properties>
|
||||
<!-- 本项目的其它module版本号 -->
|
||||
<zfoo.event.version>3.0</zfoo.event.version>
|
||||
<zfoo.hotswap.version>3.0</zfoo.hotswap.version>
|
||||
<zfoo.monitor.version>3.0</zfoo.monitor.version>
|
||||
<zfoo.net.version>3.0</zfoo.net.version>
|
||||
<zfoo.scheduler.version>3.0</zfoo.scheduler.version>
|
||||
<zfoo.storage.version>3.0</zfoo.storage.version>
|
||||
<zfoo.orm.version>3.0</zfoo.orm.version>
|
||||
<zfoo.protocol.version>3.0</zfoo.protocol.version>
|
||||
<zfoo.util.version>3.0</zfoo.util.version>
|
||||
|
||||
|
||||
<!-- 核心spring框架 -->
|
||||
<spring.version>5.3.4</spring.version>
|
||||
<spring.boot.version>2.4.3</spring.boot.version>
|
||||
|
||||
|
||||
<!-- 工具包 -->
|
||||
<commons-codec.version>1.15</commons-codec.version>
|
||||
<commons-io.version>2.8.0</commons-io.version>
|
||||
<commons-collections.version>4.4</commons-collections.version>
|
||||
<commons-lang.version>3.12.0</commons-lang.version>
|
||||
<commons-fileupload.version>1.4</commons-fileupload.version>
|
||||
<commons-logging.version>1.2</commons-logging.version>
|
||||
<commons-log4j.version>2.14.0</commons-log4j.version>
|
||||
<httpcomponents.version>4.5.13</httpcomponents.version>
|
||||
<httpcore.version>4.4.14</httpcore.version>
|
||||
<google.guava.version>30.1-jre</google.guava.version>
|
||||
<google.protobuf.version>3.9.1</google.protobuf.version>
|
||||
<google.gson.version>2.8.6</google.gson.version>
|
||||
<kryo.version>5.0.3</kryo.version>
|
||||
<caffeine.version>2.8.8</caffeine.version>
|
||||
<jctools.version>3.2.0</jctools.version>
|
||||
<hutool.version>5.5.9</hutool.version>
|
||||
<oshi.version>5.7.0</oshi.version>
|
||||
<snakeyaml.version>1.28</snakeyaml.version>
|
||||
|
||||
|
||||
<!-- json和xml解析包 -->
|
||||
<jackson.version>2.12.1</jackson.version>
|
||||
<fastjson.version>1.2.51</fastjson.version>
|
||||
<!-- office文档解析包 -->
|
||||
<poi.version>4.1.2</poi.version>
|
||||
<!-- 字节码增强 -->
|
||||
<javassist.version>3.27.0-GA</javassist.version>
|
||||
<bytebuddy.version>1.10.22</bytebuddy.version>
|
||||
|
||||
<!-- 网络通讯框架 -->
|
||||
<netty.version>4.1.63.Final</netty.version>
|
||||
|
||||
<!-- 分布式zookeeper核心依赖包 -->
|
||||
<zookeeper.version>3.6.1</zookeeper.version>
|
||||
<curator.version>5.1.0</curator.version>
|
||||
|
||||
<!-- 数据库和缓存 -->
|
||||
<mongodb-driver-sync.version>4.2.1</mongodb-driver-sync.version>
|
||||
<jedis.version>3.3.0</jedis.version>
|
||||
|
||||
<!-- 消息队列中间件 -->
|
||||
<rocketmq.version>4.5.2</rocketmq.version>
|
||||
|
||||
<!-- elastic search 中间件 -->
|
||||
<elastic.search.version>7.9.3</elastic.search.version>
|
||||
<elastic.search.spring.version>4.1.5</elastic.search.spring.version>
|
||||
<lucene.version>8.6.2</lucene.version>
|
||||
|
||||
|
||||
<slf4j.version>1.7.30</slf4j.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
|
||||
<junit.version>4.13.1</junit.version>
|
||||
|
||||
<!-- java版本和文件编码 -->
|
||||
<java.version>11</java.version>
|
||||
<file.encoding>UTF-8</file.encoding>
|
||||
<jakarta.version>1.3.5</jakarta.version>
|
||||
|
||||
<!-- maven核心插件 -->
|
||||
<maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
|
||||
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
|
||||
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
|
||||
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
|
||||
<versions-maven-plugin.version>2.8.1</versions-maven-plugin.version>
|
||||
|
||||
|
||||
<project.build.sourceEncoding>${file.encoding}</project.build.sourceEncoding>
|
||||
<maven.compiler.encoding>${file.encoding}</maven.compiler.encoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- 依赖的utils类库 -->
|
||||
<dependency>
|
||||
<groupId>com.zfoo</groupId>
|
||||
<artifactId>util</artifactId>
|
||||
<version>${zfoo.util.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 动态生成二进制字节码的javassist类库 -->
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>${javassist.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖的Spring模块类库 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- slf4j-api -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<!-- logback核心包 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<!-- logback的sl4j的实现 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖的测试库 -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
|
||||
<plugins>
|
||||
|
||||
<!-- 清理插件 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>${maven-clean-plugin.version}</version>
|
||||
</plugin>
|
||||
|
||||
<!-- 编译插件 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${file.encoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!-- resource资源管理插件 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>${maven-resources-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<encoding>${file.encoding}</encoding>
|
||||
<outputDirectory>${project.build.directory}/resource</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources/</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!-- 测试插件 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<forkMode>once</forkMode>
|
||||
<threadCount>10</threadCount>
|
||||
<argLine>-Dfile.encoding=${file.encoding}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>${maven-jar-plugin.version}</version>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event;
|
||||
|
||||
import com.zfoo.event.manager.EventBus;
|
||||
import com.zfoo.event.schema.EventRegisterProcessor;
|
||||
import com.zfoo.protocol.exception.ExceptionUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.util.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ApplicationContextEvent;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EventContext implements ApplicationListener<ApplicationContextEvent>, Ordered {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EventContext.class);
|
||||
|
||||
private static EventContext instance;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public static EventContext getEventContext() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return instance.applicationContext;
|
||||
}
|
||||
|
||||
public synchronized static void shutdown() {
|
||||
try {
|
||||
Field field = EventBus.class.getDeclaredField("executors");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
|
||||
var executors = (ExecutorService[]) ReflectionUtils.getField(field, null);
|
||||
for (ExecutorService executor : executors) {
|
||||
ThreadUtils.shutdown(executor);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error("Event thread pool failed shutdown: " + ExceptionUtils.getMessage(e));
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Event shutdown gracefully.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationContextEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent) {
|
||||
if (instance != null) {
|
||||
return;
|
||||
}
|
||||
// 初始化上下文
|
||||
EventContext.instance = this;
|
||||
instance.applicationContext = event.getApplicationContext();
|
||||
|
||||
var beanNames = applicationContext.getBeanDefinitionNames();
|
||||
var processor = applicationContext.getBean(EventRegisterProcessor.class);
|
||||
|
||||
for (var beanName : beanNames) {
|
||||
processor.postProcessAfterInitialization(applicationContext.getBean(beanName), beanName);
|
||||
}
|
||||
} else if (event instanceof ContextClosedEvent) {
|
||||
shutdown();
|
||||
ThreadUtils.shutdownForkJoinPool();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 30;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.manager;
|
||||
|
||||
import com.zfoo.event.model.anno.EventReceiver;
|
||||
import com.zfoo.event.model.event.IEvent;
|
||||
import com.zfoo.event.model.vo.EnhanceUtils;
|
||||
import com.zfoo.event.model.vo.EventReceiverDefinition;
|
||||
import com.zfoo.event.model.vo.IEventReceiver;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.util.math.RandomUtils;
|
||||
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.NotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class EventBus {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EventBus.class);
|
||||
|
||||
// 线程池的大小
|
||||
private static final int EXECUTORS_SIZE = Runtime.getRuntime().availableProcessors() * 2;
|
||||
|
||||
private static final ExecutorService[] executors;
|
||||
|
||||
private static final Map<Class<? extends IEvent>, List<IEventReceiver>> receiverMap;
|
||||
|
||||
|
||||
static {
|
||||
receiverMap = new HashMap<>();
|
||||
executors = new ExecutorService[EXECUTORS_SIZE];
|
||||
|
||||
for (int i = 0; i < executors.length; i++) {
|
||||
var namedThreadFactory = new EventThreadFactory();
|
||||
executors[i] = Executors.newSingleThreadExecutor(namedThreadFactory);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EventThreadFactory implements ThreadFactory {
|
||||
private static final AtomicInteger poolNumber = new AtomicInteger(1);
|
||||
private final ThreadGroup group;
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
private final String namePrefix;
|
||||
|
||||
EventThreadFactory() {
|
||||
var s = System.getSecurityManager();
|
||||
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
|
||||
namePrefix = "event-p" + poolNumber.getAndIncrement() + "-t";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable runnable) {
|
||||
var t = new FastThreadLocalThread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);
|
||||
t.setDaemon(false);
|
||||
t.setPriority(Thread.NORM_PRIORITY);
|
||||
t.setUncaughtExceptionHandler((thread, e) -> logger.error(thread.toString(), e));
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步抛出一个事件,会在当前线程中运行
|
||||
*
|
||||
* @param event 需要抛出的事件
|
||||
*/
|
||||
public static void syncSubmit(IEvent event) {
|
||||
var list = receiverMap.get(event.getClass());
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
doSubmit(event, list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 异步抛出一个事件,事件不在同一个线程中处理
|
||||
*
|
||||
* @param event 需要抛出的事件
|
||||
*/
|
||||
public static void asyncSubmit(IEvent event) {
|
||||
var list = receiverMap.get(event.getClass());
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executors[Math.abs(event.threadId() % EXECUTORS_SIZE)].execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doSubmit(event, list);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机获取一个线程池
|
||||
*/
|
||||
public static Executor asyncExecute() {
|
||||
return executors[RandomUtils.randomInt(EXECUTORS_SIZE)];
|
||||
}
|
||||
|
||||
private static void doSubmit(IEvent event, List<IEventReceiver> listReceiver) {
|
||||
for (var receiver : listReceiver) {
|
||||
try {
|
||||
receiver.invoke(event);
|
||||
} catch (Exception e) {
|
||||
logger.error("eventBus未知exception异常", e);
|
||||
} catch (Throwable t) {
|
||||
logger.error("eventBus未知error异常", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerEventReceiver(Object bean) {
|
||||
try {
|
||||
var clazz = bean.getClass();
|
||||
var methods = ReflectionUtils.getMethodsByAnnoInPOJOClass(clazz, EventReceiver.class);
|
||||
for (var method : methods) {
|
||||
var paramClazzs = method.getParameterTypes();
|
||||
if (paramClazzs.length != 1) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[class:{}] [method:{}] must have one parameter!", bean.getClass().getName(), method.getName()));
|
||||
}
|
||||
if (!IEvent.class.isAssignableFrom(paramClazzs[0])) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[class:{}] [method:{}] must have one [IEvent] type parameter!", bean.getClass().getName(), method.getName()));
|
||||
}
|
||||
|
||||
var eventClazz = (Class<? extends IEvent>) paramClazzs[0];
|
||||
var eventName = eventClazz.getCanonicalName();
|
||||
var methodName = method.getName();
|
||||
|
||||
if (!Modifier.isPublic(method.getModifiers())) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[class:{}] [method:{}] [event:{}] must use 'public' as modifier!", bean.getClass().getName(), methodName, eventName));
|
||||
}
|
||||
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[class:{}] [method:{}] [event:{}] can not use 'static' as modifier!", bean.getClass().getName(), methodName, eventName));
|
||||
}
|
||||
|
||||
var expectedMethodName = StringUtils.format("on{}", eventClazz.getSimpleName());
|
||||
if (!methodName.equals(expectedMethodName)) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[class:{}] [method:{}] [event:{}] expects '{}' as method name!"
|
||||
, bean.getClass().getName(), methodName, eventName, expectedMethodName));
|
||||
}
|
||||
|
||||
var receiverDefinition = new EventReceiverDefinition(bean, method, eventClazz);
|
||||
if (!receiverMap.containsKey(eventClazz)) {
|
||||
receiverMap.put(eventClazz, new LinkedList<>());
|
||||
}
|
||||
|
||||
var enhanceReceiverDefinition = EnhanceUtils.createEventReceiver(receiverDefinition);
|
||||
receiverMap.get(eventClazz).add(enhanceReceiverDefinition);
|
||||
}
|
||||
} catch (NotFoundException | CannotCompileException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.anno;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 接受时间注解
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface EventReceiver {
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.event;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.event.ApplicationContextEvent;
|
||||
|
||||
/**
|
||||
* 应用启动事件,这个使用spring自带的事件机制,自研的event事件仅用在业务逻辑
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class AppStartEvent extends ApplicationContextEvent {
|
||||
|
||||
public AppStartEvent(ApplicationContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.event;
|
||||
|
||||
import com.zfoo.util.math.RandomUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IEvent {
|
||||
|
||||
/**
|
||||
* 这个返回的是一个用于确定事件在EventBus中的哪个线程池的执行的一个参数,只有异步事件才会有作用
|
||||
* <p>
|
||||
* 比如cpu是四核,那么EventBus中的executors线程池的数量为8个,通过取余可以确定异步事件在哪个线程池中执行。
|
||||
* 如果参数是0,0 % 8 = 0,那么异步事件最终会在executors[0]表示的线程池中执行
|
||||
* 如果参数是1,1 % 8 = 1,那么异步事件最终会在executors[1]表示的线程池中执行
|
||||
* 如果参数是8,8 % 8 = 0,那么异步事件最终会在executors[0]表示的线程池中执行
|
||||
* 如果参数是9,9 % 8 = 1,那么异步事件最终会在executors[1]表示的线程池中执行
|
||||
* <p>
|
||||
* 通过返回的参数,可以轻松控制异步事件在哪个线程池中去执行。
|
||||
* 因为EventBus中的线程池都是单线程线程池,如果将一些异步事件放在同一个线程池中执行,可以不用加锁,提高程序运行的效率。
|
||||
* <p>
|
||||
* 默认返回一个随机数,这就导致如果不重写这个方法,那么异步事件有可能会在EventBus中的任何一条线程池中去执行。
|
||||
*
|
||||
* @return 线程池的执行的一个参数
|
||||
*/
|
||||
default int threadId() {
|
||||
return RandomUtils.randomInt();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.vo;
|
||||
|
||||
import com.zfoo.event.model.event.IEvent;
|
||||
import com.zfoo.event.schema.NamespaceHandler;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.util.security.IdUtils;
|
||||
import javassist.*;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class EnhanceUtils {
|
||||
|
||||
static {
|
||||
// 适配Tomcat,因为Tomcat不是用的默认的类加载器,而Javaassist用的是默认的加载器
|
||||
var classArray = new Class<?>[]{
|
||||
IEventReceiver.class,
|
||||
IEvent.class
|
||||
};
|
||||
|
||||
var classPool = ClassPool.getDefault();
|
||||
|
||||
for (var clazz : classArray) {
|
||||
if (classPool.find(clazz.getCanonicalName()) == null) {
|
||||
ClassClassPath classPath = new ClassClassPath(clazz);
|
||||
classPool.insertClassPath(classPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEventReceiver createEventReceiver(EventReceiverDefinition definition) throws NotFoundException, CannotCompileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
var classPool = ClassPool.getDefault();
|
||||
|
||||
Object bean = definition.getBean();
|
||||
Method method = definition.getMethod();
|
||||
Class<?> clazz = definition.getEventClazz();
|
||||
|
||||
// 定义类名称
|
||||
CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getCanonicalName() + StringUtils.capitalize(NamespaceHandler.EVENT) + IdUtils.getLocalIntId());
|
||||
enhanceClazz.addInterface(classPool.get(IEventReceiver.class.getCanonicalName()));
|
||||
|
||||
// 定义类中的一个成员
|
||||
CtField field = new CtField(classPool.get(bean.getClass().getCanonicalName()), "bean", enhanceClazz);
|
||||
field.setModifiers(Modifier.PRIVATE);
|
||||
enhanceClazz.addField(field);
|
||||
|
||||
// 定义类的构造器
|
||||
CtConstructor constructor = new CtConstructor(classPool.get(new String[]{bean.getClass().getCanonicalName()}), enhanceClazz);
|
||||
constructor.setBody("{this.bean=$1;}");
|
||||
constructor.setModifiers(Modifier.PUBLIC);
|
||||
enhanceClazz.addConstructor(constructor);
|
||||
|
||||
// 定义类实现的接口方法
|
||||
CtMethod invokeMethod = new CtMethod(classPool.get(void.class.getCanonicalName()), "invoke", classPool.get(new String[]{IEvent.class.getCanonicalName()}), enhanceClazz);
|
||||
invokeMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
String invokeMethodBody = "{this.bean." + method.getName() + "((" + clazz.getCanonicalName() + ")$1);}";// 强制类型转换,转换为具体的Event类型的类型
|
||||
invokeMethod.setBody(invokeMethodBody);
|
||||
enhanceClazz.addMethod(invokeMethod);
|
||||
|
||||
// 释放缓存
|
||||
enhanceClazz.detach();
|
||||
|
||||
Class<?> resultClazz = enhanceClazz.toClass(IEventReceiver.class);
|
||||
Constructor<?> resultConstructor = resultClazz.getConstructor(bean.getClass());
|
||||
IEventReceiver receiver = (IEventReceiver) resultConstructor.newInstance(bean);
|
||||
return receiver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.vo;
|
||||
|
||||
import com.zfoo.event.model.event.IEvent;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EventReceiverDefinition implements IEventReceiver {
|
||||
|
||||
|
||||
private Object bean;
|
||||
|
||||
// 被ReceiveEvent注解的方法
|
||||
private Method method;
|
||||
|
||||
// 接收的参数Class
|
||||
private Class<? extends IEvent> eventClazz;
|
||||
|
||||
public EventReceiverDefinition(Object bean, Method method, Class<? extends IEvent> eventClazz) {
|
||||
this.bean = bean;
|
||||
this.method = method;
|
||||
this.eventClazz = eventClazz;
|
||||
ReflectionUtils.makeAccessible(this.method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(IEvent event) {
|
||||
ReflectionUtils.invokeMethod(bean, method, event);
|
||||
}
|
||||
|
||||
public Object getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBean(Object bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Class<? extends IEvent> getEventClazz() {
|
||||
return eventClazz;
|
||||
}
|
||||
|
||||
public void setEventClazz(Class<? extends IEvent> eventClazz) {
|
||||
this.eventClazz = eventClazz;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.model.vo;
|
||||
|
||||
import com.zfoo.event.model.event.IEvent;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IEventReceiver {
|
||||
|
||||
void invoke(IEvent event);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.schema;
|
||||
|
||||
import com.zfoo.event.EventContext;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EventDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
public AbstractBeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
Class<?> clazz;
|
||||
String name;
|
||||
BeanDefinitionBuilder builder;
|
||||
|
||||
// 注册EventSpringContext
|
||||
clazz = EventContext.class;
|
||||
name = StringUtils.uncapitalize(clazz.getName());
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(clazz);
|
||||
parserContext.getRegistry().registerBeanDefinition(name, builder.getBeanDefinition());
|
||||
|
||||
// 注册EventRegisterProcessor,event事件处理
|
||||
clazz = EventRegisterProcessor.class;
|
||||
name = StringUtils.uncapitalize(clazz.getName());
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(clazz);
|
||||
parserContext.getRegistry().registerBeanDefinition(name, builder.getBeanDefinition());
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.schema;
|
||||
|
||||
import com.zfoo.event.EventContext;
|
||||
import com.zfoo.event.manager.EventBus;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EventRegisterProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (EventContext.getEventContext() == null) {
|
||||
return bean;
|
||||
}
|
||||
EventBus.registerEventReceiver(bean);
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event.schema;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class NamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
public static final String EVENT = "event";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
registerBeanDefinitionParser(EVENT, new EventDefinitionParser());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.zfoo.com/schema/event=com.zfoo.event.schema.NamespaceHandler
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.zfoo.com/schema/event-1.0.xsd=event-1.0.xsd
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
|
||||
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
|
||||
xmlns="http://www.zfoo.com/schema/event"
|
||||
targetNamespace="http://www.zfoo.com/schema/event"
|
||||
|
||||
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:element name="event">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event;
|
||||
|
||||
import com.zfoo.event.manager.EventBus;
|
||||
import com.zfoo.util.ThreadUtils;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Ignore
|
||||
public class ApplicationTest {
|
||||
|
||||
// 事件总线教程
|
||||
@Test
|
||||
public void startEventTest() {
|
||||
// 加载配置文件,配置文件中必须引入event
|
||||
var context = new ClassPathXmlApplicationContext("application.xml");
|
||||
|
||||
// 事件的接受需要在被Spring管理的bean的方法上加上@EventReceiver注解,即可自动注册事件的监听
|
||||
// 参考MyController1中的标准注册方法
|
||||
|
||||
// 抛出同步事件,事件会被当前线程立刻执行,注意日志打印的线程号
|
||||
EventBus.syncSubmit(MyNoticeEvent.valueOf("同步事件"));
|
||||
|
||||
// 抛出异步事件,事件会被不会立刻执行,注意日志打印的线程号
|
||||
EventBus.asyncSubmit(MyNoticeEvent.valueOf("异步事件"));
|
||||
|
||||
// 睡眠3秒,等待异步事件执行完
|
||||
ThreadUtils.sleep(3000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event;
|
||||
|
||||
import com.zfoo.event.model.anno.EventReceiver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Component
|
||||
public class MyController1 {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MyController1.class);
|
||||
|
||||
@EventReceiver
|
||||
public void onMyNoticeEvent(MyNoticeEvent event) {
|
||||
logger.info("方法1收到事件:" + event.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event;
|
||||
|
||||
import com.zfoo.event.model.anno.EventReceiver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Component
|
||||
public class MyController2 {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MyController2.class);
|
||||
|
||||
/**
|
||||
* 同一个事件可以被重复注册和接受
|
||||
*/
|
||||
@EventReceiver
|
||||
public void onMyNoticeEvent(MyNoticeEvent event) {
|
||||
logger.info("方法2收到事件:" + event.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.event;
|
||||
|
||||
import com.zfoo.event.model.event.IEvent;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class MyNoticeEvent implements IEvent {
|
||||
|
||||
private String message;
|
||||
|
||||
public static MyNoticeEvent valueOf(String message) {
|
||||
var event = new MyNoticeEvent();
|
||||
event.setMessage(message);
|
||||
return event;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?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"
|
||||
|
||||
xmlns:event="http://www.zfoo.com/schema/event"
|
||||
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-4.0.xsd
|
||||
|
||||
http://www.zfoo.com/schema/event
|
||||
http://www.zfoo.com/schema/event-1.0.xsd">
|
||||
|
||||
|
||||
<context:component-scan base-package="com.zfoo.event"/>
|
||||
|
||||
<event:event id="eventBus"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<configuration scan="false" debug="false">
|
||||
|
||||
<contextName>com.zfoo.event</contextName>
|
||||
|
||||
<property name="LOG_HOME" value="log/event"/>
|
||||
<property name="PATTERN_FILE"
|
||||
value="%d{yyyy-MM-dd HH:mm:ss} [%5level] [%thread] %logger.%M\\(%F:%line\\) - %msg%n"/>
|
||||
<property name="PATTERN_CONSOLE"
|
||||
value="%d{yyyy-MM-dd HH:mm:ss} [%highlight(%5level)] [%thread] %logger.%M\\(%F:%line\\) - %msg%n"/>
|
||||
<!-- 负责写日志,控制台日志,会打印所有的包的所有级别日志 -->
|
||||
<appender name="zfoo_console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${PATTERN_CONSOLE}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 根logger -->
|
||||
<root level="info">
|
||||
<appender-ref ref="zfoo_console"/>
|
||||
</root>
|
||||
|
||||
<!--
|
||||
- 1.name:包名或类名,用来指定受此logger约束的某一个包或者具体的某一个类
|
||||
- 2.未设置打印级别,所以继承他的上级<root>的日志级别“DEBUG”
|
||||
- 3.未设置additivity,默认为true,将此logger的打印信息向上级传递;
|
||||
- 4.未设置appender,此logger本身不打印任何信息,级别为“DEBUG”及大于“DEBUG”的日志信息传递给root,
|
||||
- root接到下级传递的信息,交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
|
||||
-->
|
||||
<logger name="ch.qos.logback" level="info"/>
|
||||
|
||||
<!--*******************************************Spring********************************************************-->
|
||||
<!--logger中的name是指代码的包名或类名,路径要写全,可以配置不同包中的日志输出到不同的文件中。level是日志输出级别 -->
|
||||
<!--过滤掉spring的一些无用的DEBUG信息-->
|
||||
<logger name="org.springframework" level="info"/>
|
||||
<!-- additivity="false"表示不继承父logger的配置和父类没有关系-->
|
||||
<logger name="org.springframework.core" level="info"/>
|
||||
|
||||
|
||||
<!--*******************************************Netty*********************************************************-->
|
||||
<logger name="io.netty" level="info"/>
|
||||
</configuration>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 992 KiB |
Reference in new issue
Block a user