Allow plugin to listen the event the plugin has started (#6234)

#### What type of PR is this?

/kind feature
/area core
/milestone 2.17.x

#### What this PR does / why we need it:

This PR add support for allowing plugin to listen the event that the plugin has started. Below is an example of listening the event in plugin:

```java
    @EventListener
    void onPluginStartedEvent(PluginStartedEvent event) {
        // do something.
    }
```

See https://github.com/halo-dev/halo/issues/5339#issuecomment-2199220068 for more.

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/5339#issuecomment-2199220068

#### Special notes for your reviewer:

1. Create a plugin, add the listener above and write some logs
2. Build and install the plugin
3. Start plugin and see the logs you wrote

#### Does this PR introduce a user-facing change?

```release-note
支持在插件中监听已启动事件
```
pull/6233/head^2
John Niang 2024-07-01 15:31:17 +08:00 committed by GitHub
parent b673e4a24f
commit 3875251d97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 36 deletions

View File

@ -0,0 +1,17 @@
package run.halo.app.plugin.event;
import org.springframework.context.ApplicationEvent;
/**
* The event that is published when a plugin is really started, and is only for plugin internal use.
*
* @author johnniang
* @since 2.17.0
*/
public class PluginStartedEvent extends ApplicationEvent {
public PluginStartedEvent(Object source) {
super(source);
}
}

View File

@ -20,11 +20,15 @@ import org.pf4j.PluginDescriptorFinder;
import org.pf4j.PluginFactory;
import org.pf4j.PluginLoader;
import org.pf4j.PluginRepository;
import org.pf4j.PluginState;
import org.pf4j.PluginStateEvent;
import org.pf4j.PluginStateListener;
import org.pf4j.PluginStatusProvider;
import org.pf4j.PluginWrapper;
import org.springframework.context.ApplicationContext;
import org.springframework.data.util.Lazy;
import run.halo.app.infra.SystemVersionSupplier;
import run.halo.app.plugin.event.PluginStartedEvent;
/**
* PluginManager to hold the main ApplicationContext.
@ -56,6 +60,9 @@ public class HaloPluginManager extends DefaultPluginManager implements SpringPlu
setSystemVersion(systemVersionSupplier.get().getNormalVersion());
super.initialize();
// the listener must be after the super#initialize
addPluginStateListener(new PluginStartedListener());
}
@Override
@ -175,4 +182,30 @@ public class HaloPluginManager extends DefaultPluginManager implements SpringPlu
}
return dependents;
}
/**
* Listener for plugin started event.
*
* @author johnniang
* @since 2.17.0
*/
private static class PluginStartedListener implements PluginStateListener {
@Override
public void pluginStateChanged(PluginStateEvent event) {
if (PluginState.STARTED.equals(event.getPluginState())) {
var plugin = event.getPlugin().getPlugin();
if (plugin instanceof SpringPlugin springPlugin) {
try {
springPlugin.getApplicationContext()
.publishEvent(new PluginStartedEvent(this));
} catch (Throwable t) {
var pluginId = event.getPlugin().getPluginId();
log.warn("Error while publishing plugin started event for plugin {}",
pluginId, t);
}
}
}
}
}
}

View File

@ -1,36 +0,0 @@
package run.halo.app.plugin.event;
import org.pf4j.PluginState;
import org.pf4j.PluginWrapper;
import org.springframework.context.ApplicationEvent;
/**
* Plugin state changed event.
*
* @author guqing
* @date 2021-11-06
*/
public class HaloPluginStateChangedEvent extends ApplicationEvent {
private final PluginWrapper plugin;
private final PluginState oldState;
public HaloPluginStateChangedEvent(Object source, PluginWrapper wrapper, PluginState oldState) {
super(source);
this.plugin = wrapper;
this.oldState = oldState;
}
public PluginWrapper getPlugin() {
return plugin;
}
public PluginState getOldState() {
return oldState;
}
public PluginState getState() {
return this.plugin.getPluginState();
}
}