diff --git a/buildSrc/src/main/kotlin/Modules.kt b/buildSrc/src/main/kotlin/Modules.kt index 4d2df04..5915d57 100644 --- a/buildSrc/src/main/kotlin/Modules.kt +++ b/buildSrc/src/main/kotlin/Modules.kt @@ -122,7 +122,7 @@ object Modules { } } object Plugin { - private const val PLUGIN = ":forgeboot-plugin" + private const val PLUGIN = ":forgeboot-plugin-spring-boot-starter" const val CORE = "${PLUGIN}:forgeboot-plugin-core" const val SPRING = "${PLUGIN}:forgeboot-plugin-spring" } diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt index 7ecce7b..e6e5179 100644 --- a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt @@ -1,10 +1,7 @@ package com.gewuyou.forgeboot.plugin.demo.impl -import com.gewuyou.forgeboot.plugin.spring.manager.SpringPluginManager +import com.gewuyou.forgeboot.plugin.spring.MergedSpringPlugin import org.pf4j.PluginWrapper -import org.pf4j.spring.SpringPlugin -import org.springframework.context.ApplicationContext -import org.springframework.context.annotation.AnnotationConfigApplicationContext /** * 简单的问候插件 @@ -16,13 +13,14 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext */ class SimpleGreetingPlugin( private val pluginWrapper: PluginWrapper, -) : SpringPlugin(pluginWrapper) { - override fun createApplicationContext(): ApplicationContext { - return AnnotationConfigApplicationContext().apply { -> - classLoader = pluginWrapper.pluginClassLoader - parent = (pluginWrapper.pluginManager as SpringPluginManager).applicationContext - register(PluginConfig::class.java) - refresh() - } +) : MergedSpringPlugin(pluginWrapper) { + /** + * 获取插件配置类 + * + * 抽象方法,子类需要提供插件特定的配置类, + * 该配置类将被注册到插件的应用上下文中。 + */ + override fun pluginConfigurationClass(): List> { + return listOf(PluginConfig::class.java) } } \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar deleted file mode 100644 index 680394a..0000000 Binary files a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar and /dev/null differ diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.1.1-SNAPSHOT.jar b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.1.1-SNAPSHOT.jar new file mode 100644 index 0000000..8fcf8c5 Binary files /dev/null and b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.1.1-SNAPSHOT.jar differ diff --git a/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/exception/PluginInitializationException.kt b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/exception/PluginInitializationException.kt new file mode 100644 index 0000000..7c56c64 --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/exception/PluginInitializationException.kt @@ -0,0 +1,15 @@ +package com.gewuyou.forgeboot.plugin.core.exception + +/** + *插件初始化异常 + * + * @since 2025-07-26 11:25:18 + * @author gewuyou + */ +class PluginInitializationException( + message: String, + cause: Throwable?, +) : RuntimeException( + message, + cause +) \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/AbstractSpringPlugin.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/AbstractSpringPlugin.kt new file mode 100644 index 0000000..ff7f86a --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/AbstractSpringPlugin.kt @@ -0,0 +1,75 @@ +package com.gewuyou.forgeboot.plugin.spring + +import com.gewuyou.forgeboot.plugin.core.exception.PluginInitializationException +import org.pf4j.PluginWrapper +import org.pf4j.spring.SpringPlugin +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import org.springframework.core.env.ConfigurableEnvironment + +/** + *抽象Spring插件 + * + * @since 2025-07-26 11:27:26 + * @author gewuyou + */ +abstract class AbstractSpringPlugin( + pluginWrapper: PluginWrapper, +) : SpringPlugin(pluginWrapper) { + /** + * 获取插件配置类 + * + * 抽象方法,子类需要提供插件特定的配置类, + * 该配置类将被注册到插件的应用上下文中。 + */ + abstract fun pluginConfigurationClass(): List> + + /** + * 构建Spring应用上下文 + * + * 该函数用于创建并配置一个AnnotationConfigApplicationContext实例, + * 包括设置类加载器、父上下文、环境配置,注册配置类并刷新上下文。 + * + * @param pluginWrapper 插件包装器,提供插件的基本信息和类加载器 + * @param parentContext 父级应用上下文,可为空 + * @param environment 可选的环境配置 + * @return 配置完成的AnnotationConfigApplicationContext实例 + */ + protected fun buildSpringContext( + pluginWrapper: PluginWrapper, + parentContext: ApplicationContext? = null, + environment: ConfigurableEnvironment? = null, + ): AnnotationConfigApplicationContext { + try { + val configClasses = pluginConfigurationClass().also { + require(it.isNotEmpty()) { + "插件 [${pluginWrapper.pluginId}] 未提供任何配置类" + } + } + + return AnnotationConfigApplicationContext().apply { + // 设置插件类加载器 + classLoader = pluginWrapper.pluginClassLoader + // 设置父级上下文 + parent = parentContext + // 如果提供了环境配置,则设置环境 + if (environment != null) { + this.environment = environment + } + // 注册所有配置类 + configClasses.forEach { register(it) } + // 刷新上下文以完成初始化 + refresh() + log.info( + "✅ 插件 [{}] 上下文加载成功,注册配置类: {}", + pluginWrapper.pluginId, + configClasses.joinToString() + ) + } + } catch (e: Exception) { + log.error("❌ 插件 [{}] 加载失败", pluginWrapper.pluginId, e) + throw PluginInitializationException("插件 [${pluginWrapper.pluginId}] 初始化失败", e) + } + } + +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt index 120802f..e4edcf9 100644 --- a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt @@ -1,9 +1,7 @@ package com.gewuyou.forgeboot.plugin.spring import org.pf4j.PluginWrapper -import org.pf4j.spring.SpringPlugin import org.springframework.context.ApplicationContext -import org.springframework.context.annotation.AnnotationConfigApplicationContext /** * 隔离的Spring插件 @@ -17,8 +15,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext * @author gewuyou */ abstract class IsolatedSpringPlugin( - private val pluginWrapper: PluginWrapper -) : SpringPlugin(pluginWrapper) { + private val pluginWrapper: PluginWrapper, +) : AbstractSpringPlugin(pluginWrapper) { /** * 创建应用上下文 @@ -29,20 +27,6 @@ abstract class IsolatedSpringPlugin( * @return 配置完成的ApplicationContext实例 */ override fun createApplicationContext(): ApplicationContext { - return AnnotationConfigApplicationContext().apply { - classLoader = pluginWrapper.pluginClassLoader - register(pluginConfigurationClass()) - refresh() - } + return buildSpringContext(pluginWrapper) } - - /** - * 获取插件配置类 - * - * 抽象方法,子类需要提供插件特定的配置类, - * 该配置类将被注册到插件的应用上下文中。 - * - * @return 插件配置类的Class对象 - */ - abstract fun pluginConfigurationClass(): Class<*> } \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt index 7c6f120..17544eb 100644 --- a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt @@ -1,10 +1,8 @@ package com.gewuyou.forgeboot.plugin.spring import org.pf4j.PluginWrapper -import org.pf4j.spring.SpringPlugin import org.pf4j.spring.SpringPluginManager import org.springframework.context.ApplicationContext -import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.core.env.ConfigurableEnvironment /** @@ -17,38 +15,20 @@ import org.springframework.core.env.ConfigurableEnvironment * @property pluginWrapper 插件包装器,提供插件的基本信息和类加载器 * * @since 2025-07-24 15:35:52 - * @author gewuyou */ abstract class MergedSpringPlugin( - private val pluginWrapper: PluginWrapper -) : SpringPlugin(pluginWrapper) { - + private val pluginWrapper: PluginWrapper, +) : AbstractSpringPlugin(pluginWrapper) { /** * 创建应用上下文 * - * 该方法覆盖了父类的实现,创建一个与主应用上下文有关联的AnnotationConfigApplicationContext, - * 设置插件的类加载器,建立父子上下文关系,并注册插件特定的配置类。 - * - * @return 配置完成的ApplicationContext实例 + * 创建一个与主应用上下文有关联的 AnnotationConfigApplicationContext, + * 设置类加载器、父上下文、环境,并注册插件配置类。 */ override fun createApplicationContext(): ApplicationContext { - return AnnotationConfigApplicationContext().apply { - classLoader = pluginWrapper.pluginClassLoader - parent = (pluginWrapper.pluginManager as SpringPluginManager).applicationContext - // 保证配置文件能读取 - environment = parent?.environment as ConfigurableEnvironment - register(pluginConfigurationClass()) - refresh() - } + val manager = pluginWrapper.pluginManager as SpringPluginManager + val parentCtx = manager.applicationContext + val env = parentCtx.environment as ConfigurableEnvironment + return buildSpringContext(pluginWrapper, parentCtx, env) } - - /** - * 获取插件配置类 - * - * 抽象方法,子类需要提供插件特定的配置类, - * 该配置类将被注册到插件的应用上下文中。 - * - * @return 插件配置类的Class对象 - */ - abstract fun pluginConfigurationClass(): Class<*> } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index fccbead..e15540c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -157,7 +157,9 @@ include( ":forgeboot-plugin:forgeboot-plugin-core", ":forgeboot-plugin:forgeboot-plugin-spring", ) - +project(":forgeboot-plugin").name = "forgeboot-plugin-spring-boot-starter" +project(":forgeboot-plugin:forgeboot-plugin-core").name = "forgeboot-plugin-core" +project(":forgeboot-plugin:forgeboot-plugin-spring").name = "forgeboot-plugin-spring" //region module cache include( "forgeboot-cache",