From 55d7b544ad1cd8e77f587c0188b56f0ab4f2faf4 Mon Sep 17 00:00:00 2001 From: John Niang Date: Fri, 26 Jan 2024 14:04:39 +0800 Subject: [PATCH] Support shared event mechanism Signed-off-by: John Niang --- ...efaultPluginApplicationContextFactory.java | 36 ++++++++++++++++++- .../DefaultSharedEventListenerRegistry.java | 34 ++++++++++++++++++ .../PluginApplicationContextFactory.java | 2 +- .../plugin/SharedEventListenerRegistry.java | 12 +++++++ .../run/halo/app/plugin/SpringPlugin.java | 1 - .../halo/app/plugin/SpringPluginFactory.java | 1 - 6 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 application/src/main/java/run/halo/app/plugin/DefaultSharedEventListenerRegistry.java rename application/src/main/java/run/halo/app/{ => plugin}/PluginApplicationContextFactory.java (91%) create mode 100644 application/src/main/java/run/halo/app/plugin/SharedEventListenerRegistry.java diff --git a/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java b/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java index 7fb283ebde..7142016a6a 100644 --- a/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java +++ b/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java @@ -14,6 +14,7 @@ import org.springframework.boot.env.PropertySourceLoader; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; @@ -28,7 +29,6 @@ import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.Exceptions; -import run.halo.app.PluginApplicationContextFactory; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.infra.properties.HaloProperties; import run.halo.app.plugin.event.HaloPluginBeforeStopEvent; @@ -133,6 +133,15 @@ public ApplicationContext create(String pluginId) { pluginRouterFunctionManager ); }); + + rootContext.getBeanProvider(SharedEventListenerRegistry.class) + .ifUnique(listenerRegistry -> { + var shareEventListenerAdapter = new ShareEventListenerAdapter(listenerRegistry); + beanFactory.registerSingleton( + "shareEventListenerAdapter", + shareEventListenerAdapter + ); + }); sw.stop(); sw.start("LoadComponents"); @@ -162,6 +171,31 @@ public ApplicationContext create(String pluginId) { return context; } + private static class ShareEventListenerAdapter { + + private final SharedEventListenerRegistry listenerRegistry; + + private ApplicationListener listener; + + private ShareEventListenerAdapter(SharedEventListenerRegistry listenerRegistry) { + this.listenerRegistry = listenerRegistry; + } + + @EventListener + public void onApplicationEvent(ContextRefreshedEvent event) { + this.listener = sharedEvent -> event.getApplicationContext().publishEvent(sharedEvent); + listenerRegistry.register(this.listener); + } + + @EventListener(ContextClosedEvent.class) + public void onApplicationEvent() { + if (this.listener != null) { + this.listenerRegistry.unregister(this.listener); + } + } + + } + private static class FinderManager { private final String pluginId; diff --git a/application/src/main/java/run/halo/app/plugin/DefaultSharedEventListenerRegistry.java b/application/src/main/java/run/halo/app/plugin/DefaultSharedEventListenerRegistry.java new file mode 100644 index 0000000000..28ab808411 --- /dev/null +++ b/application/src/main/java/run/halo/app/plugin/DefaultSharedEventListenerRegistry.java @@ -0,0 +1,34 @@ +package run.halo.app.plugin; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +@Component +public class DefaultSharedEventListenerRegistry implements + ApplicationListener, SharedEventListenerRegistry { + + private final List> listeners; + + public DefaultSharedEventListenerRegistry() { + listeners = new CopyOnWriteArrayList<>(); + } + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (!event.getClass().isAnnotationPresent(SharedEvent.class)) { + return; + } + listeners.forEach(listener -> listener.onApplicationEvent(event)); + } + + public void register(ApplicationListener listener) { + this.listeners.add(listener); + } + + public void unregister(ApplicationListener listener) { + this.listeners.remove(listener); + } +} diff --git a/application/src/main/java/run/halo/app/PluginApplicationContextFactory.java b/application/src/main/java/run/halo/app/plugin/PluginApplicationContextFactory.java similarity index 91% rename from application/src/main/java/run/halo/app/PluginApplicationContextFactory.java rename to application/src/main/java/run/halo/app/plugin/PluginApplicationContextFactory.java index cccb9cebbf..e8f3ef0c7b 100644 --- a/application/src/main/java/run/halo/app/PluginApplicationContextFactory.java +++ b/application/src/main/java/run/halo/app/plugin/PluginApplicationContextFactory.java @@ -1,4 +1,4 @@ -package run.halo.app; +package run.halo.app.plugin; import org.springframework.context.ApplicationContext; diff --git a/application/src/main/java/run/halo/app/plugin/SharedEventListenerRegistry.java b/application/src/main/java/run/halo/app/plugin/SharedEventListenerRegistry.java new file mode 100644 index 0000000000..8ad73ce44c --- /dev/null +++ b/application/src/main/java/run/halo/app/plugin/SharedEventListenerRegistry.java @@ -0,0 +1,12 @@ +package run.halo.app.plugin; + +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; + +public interface SharedEventListenerRegistry { + + void register(ApplicationListener listener); + + void unregister(ApplicationListener listener); + +} diff --git a/application/src/main/java/run/halo/app/plugin/SpringPlugin.java b/application/src/main/java/run/halo/app/plugin/SpringPlugin.java index c80842128f..2f6624f8dc 100644 --- a/application/src/main/java/run/halo/app/plugin/SpringPlugin.java +++ b/application/src/main/java/run/halo/app/plugin/SpringPlugin.java @@ -3,7 +3,6 @@ import org.pf4j.Plugin; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; -import run.halo.app.PluginApplicationContextFactory; import run.halo.app.plugin.event.SpringPluginStartedEvent; import run.halo.app.plugin.event.SpringPluginStartingEvent; import run.halo.app.plugin.event.SpringPluginStoppingEvent; diff --git a/application/src/main/java/run/halo/app/plugin/SpringPluginFactory.java b/application/src/main/java/run/halo/app/plugin/SpringPluginFactory.java index da4fa015b2..f463e1d457 100644 --- a/application/src/main/java/run/halo/app/plugin/SpringPluginFactory.java +++ b/application/src/main/java/run/halo/app/plugin/SpringPluginFactory.java @@ -4,7 +4,6 @@ import org.pf4j.Plugin; import org.pf4j.PluginFactory; import org.pf4j.PluginWrapper; -import run.halo.app.PluginApplicationContextFactory; /** * The default implementation for PluginFactory.