diff --git a/pom.xml b/pom.xml index 0970aa19b590cfb7a29c6397b463736fc7a26190..c14f89711f0c10b51bc7eaec0ad7bd0633712234 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.gitee.starblues spring-brick-parent pom - 3.0.3 + 3.1.0 spring-brick-common diff --git a/spring-brick-bootstrap/pom.xml b/spring-brick-bootstrap/pom.xml index cf32d07c87bc0dc4ffc13fbc594c07a843896f0b..d6cf302bfff1524883870ca43f6fbf5c2e8923c8 100644 --- a/spring-brick-bootstrap/pom.xml +++ b/spring-brick-bootstrap/pom.xml @@ -7,7 +7,7 @@ spring-brick-parent com.gitee.starblues - 3.0.3 + 3.1.0 spring-brick-bootstrap diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.java index cdbf3454fd4b0eb504eeccb16840c68075005ae1..3941f870e2027a347ee90f7502366d230dc9b417 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.java @@ -31,43 +31,15 @@ import java.util.Set; /** * @author starBlues * @since 3.0.3 - * @version 3.0.3 + * @version 3.1.0 */ -public class AutowiredTypeResolver { - - private final Set classDefiners; - private final PathMatcher pathMatcher = new AntPathMatcher(); - - - public AutowiredTypeResolver(ProcessorContext processorContext) { - AutowiredTypeDefiner autowiredTypeDefiner = processorContext.getSpringPluginBootstrap().autowiredTypeDefiner(); - if(autowiredTypeDefiner != null){ - AutowiredTypeDefinerConfig definerConfig = new AutowiredTypeDefinerConfig(); - autowiredTypeDefiner.config(definerConfig); - classDefiners = definerConfig.getClassDefiners(); - } else { - classDefiners = Collections.emptySet(); - } - } - - public AutowiredType.Type resolve(DependencyDescriptor descriptor){ - String name = descriptor.getDependencyType().getName(); - String classNamePath = UrlUtils.formatMatchUrl(name); - for (AutowiredTypeDefiner.ClassDefiner classDefiner : classDefiners) { - Set classNamePatterns = classDefiner.getClassNamePatterns(); - for (String classNamePattern : classNamePatterns) { - if(pathMatcher.match(classNamePattern, classNamePath)){ - return classDefiner.getAutowiredType(); - } - } - } - AutowiredType autowiredType = descriptor.getAnnotation(AutowiredType.class); - if(autowiredType != null){ - return autowiredType.value(); - } else { - return AutowiredType.Type.PLUGIN; - } - } - +public interface AutowiredTypeResolver { + + /** + * 通过 descriptor 获取注入类型 + * @param descriptor descriptor + * @return AutowiredType.Type + */ + AutowiredType.Type resolve(DependencyDescriptor descriptor); } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigurePluginEnvironment.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigurePluginEnvironment.java index 67ba59416d5028bf0648ee32f14b546f416fd5e6..536b4e34b97681207e6645a6d5aa3d79eb9aa555 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigurePluginEnvironment.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigurePluginEnvironment.java @@ -19,15 +19,20 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.integration.AutoIntegrationConfiguration; +import com.gitee.starblues.loader.launcher.DevelopmentModeSetting; import com.gitee.starblues.utils.Assert; import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.ObjectUtils; import com.gitee.starblues.utils.PluginFileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.LiveBeansView; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import java.io.File; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -36,7 +41,8 @@ import java.util.Map; * @author starBlues * @version 3.0.0 */ -class ConfigurePluginEnvironment { +public class ConfigurePluginEnvironment { + private final Logger logger = LoggerFactory.getLogger(ConfigurePluginEnvironment.class); private final static String PLUGIN_PROPERTY_NAME = "pluginPropertySources"; @@ -53,13 +59,13 @@ class ConfigurePluginEnvironment { private final ProcessorContext processorContext; private final InsidePluginDescriptor pluginDescriptor; - ConfigurePluginEnvironment(ProcessorContext processorContext) { + public ConfigurePluginEnvironment(ProcessorContext processorContext) { this.processorContext = Assert.isNotNull(processorContext, "processorContext 不能为空"); this.pluginDescriptor = Assert.isNotNull(processorContext.getPluginDescriptor(), "pluginDescriptor 不能为空"); } - void configureEnvironment(ConfigurableEnvironment environment, String[] args) { + public void configureEnvironment(ConfigurableEnvironment environment, String[] args) { Map env = new HashMap<>(); String pluginId = pluginDescriptor.getPluginId(); String configFileName = pluginDescriptor.getConfigFileName(); @@ -75,13 +81,22 @@ class ConfigurePluginEnvironment { env.put(SPRING_ADMIN_JMX_NAME, SPRING_ADMIN_JMX_VALUE + pluginId); env.put(REGISTER_SHUTDOWN_HOOK_PROPERTY, false); env.put(MBEAN_DOMAIN_PROPERTY_NAME, pluginId); - environment.getPropertySources().addFirst(new MapPropertySource(PLUGIN_PROPERTY_NAME, env)); - if(processorContext.runMode() == ProcessorContext.RunMode.ONESELF){ - ConfigureMainPluginEnvironment configureMainPluginEnvironment = - new ConfigureMainPluginEnvironment(processorContext); - configureMainPluginEnvironment.configureEnvironment(environment, args); + try{ + // fix: https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I57965 + // 优先注册LiveBeansView对象,防止注册异常 + Method method = LiveBeansView.class.getDeclaredMethod("registerApplicationContext", ConfigurableApplicationContext.class); + method.setAccessible(true); + method.invoke(null,processorContext.getApplicationContext()); + } catch (Exception ex){ + logger.error("LiveBeansView.registerApplicationContext失败. {}", ex.getMessage(), ex); + } + + if(DevelopmentModeSetting.coexist()){ + env.put(AutoIntegrationConfiguration.ENABLE_STARTER_KEY, false); } + + environment.getPropertySources().addFirst(new MapPropertySource(PLUGIN_PROPERTY_NAME, env)); } private String getConfigFileLocation(String configFileLocation){ diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultAutowiredTypeResolver.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultAutowiredTypeResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..ef58144198d37982036cc12b15b6a7f37fa7de2a --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultAutowiredTypeResolver.java @@ -0,0 +1,76 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap; + +import com.gitee.starblues.bootstrap.annotation.AutowiredType; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.realize.AutowiredTypeDefiner; +import com.gitee.starblues.utils.UrlUtils; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; + +import java.util.Collections; +import java.util.Set; + +/** + * 默认的 AutowiredTypeResolver 实现 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class DefaultAutowiredTypeResolver implements AutowiredTypeResolver{ + + + private final Set classDefiners; + private final PathMatcher pathMatcher = new AntPathMatcher(); + + + public DefaultAutowiredTypeResolver(ProcessorContext processorContext) { + AutowiredTypeDefiner autowiredTypeDefiner = processorContext.getSpringPluginBootstrap().autowiredTypeDefiner(); + if(autowiredTypeDefiner != null){ + AutowiredTypeDefinerConfig definerConfig = new AutowiredTypeDefinerConfig(); + autowiredTypeDefiner.config(definerConfig); + classDefiners = definerConfig.getClassDefiners(); + } else { + classDefiners = Collections.emptySet(); + } + } + + @Override + public AutowiredType.Type resolve(DependencyDescriptor descriptor){ + String name = descriptor.getDependencyType().getName(); + String classNamePath = UrlUtils.formatMatchUrl(name); + for (AutowiredTypeDefiner.ClassDefiner classDefiner : classDefiners) { + Set classNamePatterns = classDefiner.getClassNamePatterns(); + for (String classNamePattern : classNamePatterns) { + if(pathMatcher.match(classNamePattern, classNamePath)){ + return classDefiner.getAutowiredType(); + } + } + } + AutowiredType autowiredType = descriptor.getAnnotation(AutowiredType.class); + if(autowiredType != null){ + return autowiredType.value(); + } else { + return AutowiredType.Type.PLUGIN; + } + } + + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultSpringPluginHook.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultSpringPluginHook.java index 7e47ff442de99e8e45e2ca9ae8d38b443e44cbf8..bd3fdb21f6f94964df5e6f83d56009a6bf3eb139 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultSpringPluginHook.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/DefaultSpringPluginHook.java @@ -23,6 +23,7 @@ import com.gitee.starblues.bootstrap.realize.PluginCloseListener; import com.gitee.starblues.bootstrap.realize.StopValidator; import com.gitee.starblues.bootstrap.utils.DestroyUtils; import com.gitee.starblues.bootstrap.utils.SpringBeanUtils; +import com.gitee.starblues.core.PluginCloseType; import com.gitee.starblues.core.exception.PluginProhibitStopException; import com.gitee.starblues.spring.ApplicationContext; import com.gitee.starblues.spring.ApplicationContextProxy; @@ -38,12 +39,13 @@ import java.util.Map; /** * 默认的插件钩子器 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public class DefaultSpringPluginHook implements SpringPluginHook { - private final SpringPluginProcessor pluginProcessor; - private final ProcessorContext processorContext; + protected final SpringPluginProcessor pluginProcessor; + protected final ProcessorContext processorContext; private final StopValidator stopValidator; public DefaultSpringPluginHook(SpringPluginProcessor pluginProcessor, @@ -76,18 +78,18 @@ public class DefaultSpringPluginHook implements SpringPluginHook { @Override - public void close() throws Exception{ + public void close(PluginCloseType closeType) throws Exception{ try { GenericApplicationContext applicationContext = processorContext.getApplicationContext(); - callPluginCloseListener(applicationContext); + callPluginCloseListener(applicationContext, closeType); pluginProcessor.close(processorContext); - if(applicationContext != null){ - applicationContext.close(); - } + applicationContext.close(); processorContext.clearRegistryInfo(); DestroyUtils.destroyAll(null, SpringFactoriesLoader.class, "cache", Map.class); } catch (Exception e){ e.printStackTrace(); + } finally { + SpringPluginBootstrapBinder.remove(); } } @@ -106,7 +108,7 @@ public class DefaultSpringPluginHook implements SpringPluginHook { return processorContext.getRegistryInfo(PluginThymeleafProcessor.CONFIG_KEY); } - private void callPluginCloseListener(GenericApplicationContext applicationContext){ + private void callPluginCloseListener(GenericApplicationContext applicationContext, PluginCloseType closeType){ List pluginCloseListeners = SpringBeanUtils.getBeans( applicationContext, PluginCloseListener.class); if(pluginCloseListeners.isEmpty()){ @@ -114,7 +116,7 @@ public class DefaultSpringPluginHook implements SpringPluginHook { } for (PluginCloseListener pluginCloseListener : pluginCloseListeners) { try { - pluginCloseListener.close(processorContext.getPluginDescriptor()); + pluginCloseListener.close(applicationContext, processorContext.getPluginInfo(), closeType); } catch (Exception e){ e.printStackTrace(); } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java index 7608046cae2e2f9f2d41522922e8c80dcb2d4026..b83c3f826fec02e1f76840c37a7232b90ea89c8e 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java @@ -39,6 +39,11 @@ public class EmptyMainApplicationContext implements MainApplicationContext { return springBeanFactory; } + @Override + public Object getSourceBeanFactory() { + return null; + } + @Override public void close() throws Exception { @@ -64,4 +69,9 @@ public class EmptyMainApplicationContext implements MainApplicationContext { return false; } + @Override + public Object getSourceApplicationContext() { + return null; + } + } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginApplicationContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginApplicationContext.java index b6c9cb144c2c80fdad11572076ff3854c6235e9c..be1181ad59ccd5fde0da0b3c6f24c3ca5ea679d3 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginApplicationContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginApplicationContext.java @@ -20,8 +20,6 @@ import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.core.descriptor.PluginDescriptor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.java index 7c69c391c44890ee45e68ad11c41df9d666c38af..b1265330696c6f70c964fa6a21fa7550b3d39efc 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.java @@ -16,57 +16,131 @@ package com.gitee.starblues.bootstrap; +import com.gitee.starblues.bootstrap.coexist.CoexistAllowAutoConfiguration; +import com.gitee.starblues.common.PluginDisableAutoConfig; +import com.gitee.starblues.loader.launcher.DevelopmentModeSetting; import com.gitee.starblues.utils.ObjectUtils; import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter; import org.springframework.boot.autoconfigure.AutoConfigurationMetadata; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * 插件禁用的 AutoConfiguration * * @author starBlues - * @version 3.0.3 + * @version 3.1.0 + * @since 3.0.3 */ public class PluginDisableAutoConfiguration implements AutoConfigurationImportFilter { - private static final List DISABLE_FUZZY_CLASSES = new ArrayList<>(); + private static final ThreadLocal LAUNCH_PLUGIN = new ThreadLocal(); public PluginDisableAutoConfiguration(){ - addDisableFuzzyClasses(); + + } + + public static void setLaunchPlugin() { + LAUNCH_PLUGIN.set(true); } - private void addDisableFuzzyClasses() { - DISABLE_FUZZY_CLASSES.add("org.springframework.boot.autoconfigure.http"); - DISABLE_FUZZY_CLASSES.add("org.springframework.boot.autoconfigure.web"); - DISABLE_FUZZY_CLASSES.add("org.springframework.boot.autoconfigure.websocket"); - DISABLE_FUZZY_CLASSES.add("org.springframework.boot.autoconfigure.jackson"); - DISABLE_FUZZY_CLASSES.add("org.springframework.boot.autoconfigure.webservices"); + @Override + public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { + if(DevelopmentModeSetting.isolation()){ + return new IsolationDisableAutoConfiguration().match(autoConfigurationClasses, autoConfigurationMetadata); + } else if(DevelopmentModeSetting.coexist()){ + return new CoexistDisableAutoConfiguration().match(autoConfigurationClasses, autoConfigurationMetadata); + } else { + boolean[] permitAll = new boolean[autoConfigurationClasses.length]; + for (int i = 0; i < autoConfigurationClasses.length; i++) { + permitAll[i] = permit( + PluginDisableAutoConfig.getCommonPluginDisableAutoConfig(), + autoConfigurationClasses[i]); + } + return permitAll; + } } - public static boolean isDisabled(String className){ + private static boolean permit(Collection disableCollection, String className){ if(ObjectUtils.isEmpty(className)){ - return false; + return true; } - for (String disableFuzzyClass : DISABLE_FUZZY_CLASSES) { + for (String disableFuzzyClass : disableCollection) { if (className.contains(disableFuzzyClass)) { - return true; + return false; } } - return false; + return true; } - @Override - public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { - boolean[] match = new boolean[autoConfigurationClasses.length]; - for (int i = 0; i < autoConfigurationClasses.length; i++) { - String autoConfigurationClass = autoConfigurationClasses[i]; - if(autoConfigurationClass == null || "".equals(autoConfigurationClass)){ - continue; + private static class IsolationDisableAutoConfiguration implements AutoConfigurationImportFilter{ + + private final List disableFuzzyClass = new ArrayList<>(); + + IsolationDisableAutoConfiguration(){ + addDisableFuzzyClasses(); + } + + private void addDisableFuzzyClasses() { + disableFuzzyClass.add("org.springframework.boot.autoconfigure.http"); + disableFuzzyClass.add("org.springframework.boot.autoconfigure.web"); + disableFuzzyClass.add("org.springframework.boot.autoconfigure.websocket"); + disableFuzzyClass.add("org.springframework.boot.autoconfigure.jackson"); + disableFuzzyClass.add("org.springframework.boot.autoconfigure.webservices"); + disableFuzzyClass.addAll(PluginDisableAutoConfig.getCommonPluginDisableAutoConfig()); + } + + @Override + public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { + boolean[] match = new boolean[autoConfigurationClasses.length]; + for (int i = 0; i < autoConfigurationClasses.length; i++) { + String autoConfigurationClass = autoConfigurationClasses[i]; + if(autoConfigurationClass == null || "".equals(autoConfigurationClass)){ + continue; + } + match[i] = permit(disableFuzzyClass, autoConfigurationClass); + } + return match; + } + } + + + private static class CoexistDisableAutoConfiguration implements AutoConfigurationImportFilter{ + + public CoexistDisableAutoConfiguration(){ + + } + + @Override + public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { + Boolean launchPlugin = LAUNCH_PLUGIN.get(); + boolean[] match = new boolean[autoConfigurationClasses.length]; + try { + if(launchPlugin != null && launchPlugin){ + CoexistAllowAutoConfiguration configuration = SpringPluginBootstrapBinder.get() + .getCoexistAllowAutoConfiguration(); + for (int i = 0; i < autoConfigurationClasses.length; i++) { + String autoConfigurationClass = autoConfigurationClasses[i]; + if(ObjectUtils.isEmpty(autoConfigurationClass)){ + continue; + } + if(permit(PluginDisableAutoConfig.getCommonPluginDisableAutoConfig(), autoConfigurationClass)){ + match[i] = configuration.match(autoConfigurationClass); + } else { + match[i] = false; + } + } + return match; + } else { + for (int i = 0; i < autoConfigurationClasses.length; i++) { + match[i] = true; + } + } + return match; + } finally { + LAUNCH_PLUGIN.remove(); } - match[i] = !isDisabled(autoConfigurationClass); } - return match; } + } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginListableBeanFactory.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginListableBeanFactory.java index 76e8f7f9917a145fb89fb57aab44c20a46d11ebc..b9ff5c4332bf037185d4b6ccaf8ab11a032cc415 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginListableBeanFactory.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginListableBeanFactory.java @@ -22,6 +22,7 @@ import com.gitee.starblues.bootstrap.utils.DestroyUtils; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.utils.ReflectionUtils; +import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -49,11 +50,17 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { private static final Logger LOG = LoggerFactory.getLogger(PluginListableBeanFactory.class); private final MainApplicationContext applicationContext; - private final AutowiredTypeResolver autowiredTypeResolver; + + @Setter + private AutowiredTypeResolver autowiredTypeResolver; public PluginListableBeanFactory(ProcessorContext processorContext) { this.applicationContext = processorContext.getMainApplicationContext(); - this.autowiredTypeResolver = new AutowiredTypeResolver(processorContext); + this.autowiredTypeResolver = getAutowiredTypeResolver(processorContext); + } + + protected AutowiredTypeResolver getAutowiredTypeResolver(ProcessorContext processorContext){ + return new DefaultAutowiredTypeResolver(processorContext); } @SuppressWarnings("unchecked") diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java index 2723562b3900b353b4b1356d7fc15c7dda37774a..6d13acabab20533e6b5f22f9a1c0ed5e05b62582 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java @@ -17,6 +17,8 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.core.DefaultPluginInsideInfo; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.DevPluginDescriptorLoader; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.descriptor.PluginDescriptorLoader; @@ -37,27 +39,33 @@ import java.nio.file.Paths; /** * 插件自己的Interactive * @author starBlues - * @version 3.0.0 + * @version 3.1.0 */ public class PluginOneselfInteractive implements PluginInteractive { - private final InsidePluginDescriptor pluginDescriptor; + private final PluginInsideInfo pluginInsideInfo; private final MainApplicationContext mainApplicationContext; private final IntegrationConfiguration configuration; private final InvokeSupperCache invokeSupperCache; private final OpExtractFactory opExtractFactory; public PluginOneselfInteractive(){ - this.pluginDescriptor = createPluginDescriptor(); + this.pluginInsideInfo = createPluginInsideInfo(); this.mainApplicationContext = new EmptyMainApplicationContext(); this.configuration = new AutoIntegrationConfiguration(); this.invokeSupperCache = new DefaultInvokeSupperCache(); this.opExtractFactory = new DefaultOpExtractFactory(); } + @Override public InsidePluginDescriptor getPluginDescriptor() { - return pluginDescriptor; + return pluginInsideInfo.getPluginDescriptor(); + } + + @Override + public PluginInsideInfo getPluginInsideInfo() { + return pluginInsideInfo; } @Override @@ -80,7 +88,7 @@ public class PluginOneselfInteractive implements PluginInteractive { return opExtractFactory; } - private InsidePluginDescriptor createPluginDescriptor(){ + private PluginInsideInfo createPluginInsideInfo(){ EmptyPluginDescriptorDecrypt descriptorDecrypt = new EmptyPluginDescriptorDecrypt(); try (PluginDescriptorLoader pluginDescriptorLoader = new DevPluginDescriptorLoader(descriptorDecrypt)){ Path classesPath = Paths.get(this.getClass().getResource("/").toURI()).getParent(); @@ -89,7 +97,7 @@ public class PluginOneselfInteractive implements PluginInteractive { if(pluginDescriptor == null){ throw new RuntimeException("没有发现插件信息, 请使用框架提供的Maven插件器对插件进行编译!"); } - return pluginDescriptor; + return new DefaultPluginInsideInfo(pluginDescriptor); } catch (Exception e){ throw new RuntimeException(e); } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfSpringApplication.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfSpringApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..b49e658848ac43c05306fa2803cd02ebe95779dc --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfSpringApplication.java @@ -0,0 +1,80 @@ +package com.gitee.starblues.bootstrap; + +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.bootstrap.processor.oneself.ConfigureMainPluginEnvironment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + * 插件自主启动的 SpringApplication + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class PluginOneselfSpringApplication extends SpringApplication { + + private final Logger logger = LoggerFactory.getLogger(PluginSpringApplication.class); + + protected final SpringPluginProcessor pluginProcessor; + protected final ProcessorContext processorContext; + + private final ConfigurePluginEnvironment configurePluginEnvironment; + private final GenericApplicationContext applicationContext; + + + public PluginOneselfSpringApplication(SpringPluginProcessor pluginProcessor, + ProcessorContext processorContext, + Class... primarySources) { + super(primarySources); + this.pluginProcessor = pluginProcessor; + this.processorContext = processorContext; + this.configurePluginEnvironment = new ConfigurePluginEnvironment(processorContext); + this.applicationContext = getApplicationContext(); + } + + protected GenericApplicationContext getApplicationContext() { + return (GenericApplicationContext) super.createApplicationContext(); + } + + @Override + protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { + super.configureEnvironment(environment, args); + configurePluginEnvironment.configureEnvironment(environment, args); + new ConfigureMainPluginEnvironment(processorContext).configureEnvironment(environment, args); + } + + @Override + protected ConfigurableApplicationContext createApplicationContext() { + return this.applicationContext; + } + + @Override + public ConfigurableApplicationContext run(String... args) { + try { + processorContext.setApplicationContext(this.applicationContext); + PluginContextHolder.initialize(processorContext); + pluginProcessor.initialize(processorContext); + return super.run(args); + } catch (Exception e) { + pluginProcessor.failure(processorContext); + logger.debug("启动插件[{}]失败. {}", + processorContext.getPluginDescriptor().getPluginId(), + e.getMessage(), e); + throw new RuntimeException(e); + } + } + + @Override + protected void refresh(ConfigurableApplicationContext applicationContext) { + pluginProcessor.refreshBefore(processorContext); + super.refresh(applicationContext); + pluginProcessor.refreshAfter(processorContext); + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginSpringApplication.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginSpringApplication.java index d923a1b0399f207ec8a7519fd8ea587c46dab0d2..c21fc3fec436bfa1b2b5a15a0676ccd6f20717e3 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginSpringApplication.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginSpringApplication.java @@ -18,7 +18,6 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; -import com.gitee.starblues.spring.ApplicationContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -34,41 +33,35 @@ import org.springframework.core.io.ResourceLoader; /** * 插件SpringApplication实现 * @author starBlues - * @version 3.0.3 + * @since 3.0.0 + * @version 3.1.0 */ public class PluginSpringApplication extends SpringApplication { private final Logger logger = LoggerFactory.getLogger(PluginSpringApplication.class); - private final ProcessorContext.RunMode runMode; - - private final SpringPluginProcessor pluginProcessor; - private final ProcessorContext processorContext; + protected final SpringPluginProcessor pluginProcessor; + protected final ProcessorContext processorContext; + private final ConfigurePluginEnvironment configurePluginEnvironment; private final GenericApplicationContext applicationContext; - - private final DefaultListableBeanFactory beanFactory; private final ResourceLoader resourceLoader; - private final ConfigurePluginEnvironment configurePluginEnvironment; + public PluginSpringApplication(SpringPluginProcessor pluginProcessor, ProcessorContext processorContext, Class... primarySources) { super(primarySources); - this.runMode = processorContext.runMode(); this.pluginProcessor = pluginProcessor; this.processorContext = processorContext; this.resourceLoader = processorContext.getResourceLoader(); - this.beanFactory = new PluginListableBeanFactory(processorContext); this.configurePluginEnvironment = new ConfigurePluginEnvironment(processorContext); this.applicationContext = getApplicationContext(); setDefaultPluginConfig(); } protected GenericApplicationContext getApplicationContext(){ - if(runMode == ProcessorContext.RunMode.ONESELF){ - return (GenericApplicationContext) super.createApplicationContext(); - } + DefaultListableBeanFactory beanFactory = getBeanFactory(processorContext); if(processorContext.getMainApplicationContext().isWebEnvironment()){ return new PluginWebApplicationContext(beanFactory, processorContext); } else { @@ -76,15 +69,17 @@ public class PluginSpringApplication extends SpringApplication { } } + protected DefaultListableBeanFactory getBeanFactory(ProcessorContext processorContext){ + return new PluginListableBeanFactory(processorContext); + } + public void setDefaultPluginConfig(){ - if(runMode == ProcessorContext.RunMode.PLUGIN){ - setResourceLoader(resourceLoader); - setBannerMode(Banner.Mode.OFF); - setEnvironment(new StandardEnvironment()); - setWebApplicationType(WebApplicationType.NONE); - setRegisterShutdownHook(false); - setLogStartupInfo(false); - } + setResourceLoader(resourceLoader); + setBannerMode(Banner.Mode.OFF); + setEnvironment(new StandardEnvironment()); + setWebApplicationType(WebApplicationType.NONE); + setRegisterShutdownHook(false); + setLogStartupInfo(false); } @Override diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrap.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrap.java index 14d882af9c0bc7a1e033835b6b2548e3b3838a89..096984e5c775cba99f09f2617feba5c20964de39 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrap.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrap.java @@ -16,13 +16,14 @@ package com.gitee.starblues.bootstrap; -import com.gitee.starblues.bootstrap.processor.ComposeSpringPluginProcessor; -import com.gitee.starblues.bootstrap.processor.DefaultProcessorContext; +import com.gitee.starblues.bootstrap.coexist.CoexistAllowAutoConfiguration; +import com.gitee.starblues.bootstrap.launcher.*; import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; import com.gitee.starblues.bootstrap.realize.AutowiredTypeDefiner; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; import com.gitee.starblues.spring.SpringPluginHook; +import lombok.Getter; import java.util.ArrayList; import java.util.List; @@ -35,11 +36,20 @@ import java.util.List; */ public abstract class SpringPluginBootstrap { + @Getter private ProcessorContext.RunMode runMode = ProcessorContext.RunMode.ONESELF; - + @Getter private volatile PluginInteractive pluginInteractive; - + @Getter private final List customPluginProcessors = new ArrayList<>(); + @Getter + private final CoexistAllowAutoConfiguration coexistAllowAutoConfiguration = new CoexistAllowAutoConfiguration(); + + private final BootstrapLauncherFactory launcherFactory = new DefaultBootstrapLauncherFactory(); + + public SpringPluginBootstrap() { + SpringPluginBootstrapBinder.set(this); + } public final SpringPluginHook run(String[] args){ return run(this.getClass(), args); @@ -54,18 +64,11 @@ public abstract class SpringPluginBootstrap { } private SpringPluginHook start(Class[] primarySources, String[] args){ + configCoexistAllowAutoConfiguration(this.coexistAllowAutoConfiguration); createPluginInteractive(); addCustomSpringPluginProcessor(); - SpringPluginProcessor pluginProcessor = new ComposeSpringPluginProcessor(runMode, customPluginProcessors); - ProcessorContext processorContext = new DefaultProcessorContext( - runMode, this, pluginInteractive, this.getClass() - ); - PluginSpringApplication springApplication = new PluginSpringApplication( - pluginProcessor, - processorContext, - primarySources); - springApplication.run(args); - return new DefaultSpringPluginHook(pluginProcessor, processorContext); + BootstrapLauncher bootstrapLauncher = launcherFactory.create(this); + return bootstrapLauncher.launch(primarySources, args); } public final SpringPluginBootstrap setPluginInteractive(PluginInteractive pluginInteractive) { @@ -107,5 +110,12 @@ public abstract class SpringPluginBootstrap { return null; } + /** + * 在 Coexist 模式下手动配置 spring-boot-auto-configuration 类 + * @param configuration 配置的类 + */ + protected void configCoexistAllowAutoConfiguration(CoexistAllowAutoConfiguration configuration){ + + } } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrapBinder.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrapBinder.java new file mode 100644 index 0000000000000000000000000000000000000000..da40ce7d09b0251645384be64d0ed177e97eabeb --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrapBinder.java @@ -0,0 +1,28 @@ +package com.gitee.starblues.bootstrap; + +/** + * SpringPluginBootstrap 实例绑者 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class SpringPluginBootstrapBinder { + + private final static ThreadLocal BINDER = new ThreadLocal<>(); + + + public static SpringPluginBootstrap get(){ + return BINDER.get(); + } + + public static void set(SpringPluginBootstrap bootstrap){ + BINDER.set(bootstrap); + } + + public static void remove(){ + BINDER.remove(); + } + + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/ResolveClassLoader.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/ResolveClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..a93ffe05005ed909aa9a85477101b625998360ed --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/ResolveClassLoader.java @@ -0,0 +1,32 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.annotation; + +import java.lang.annotation.*; + +/** + * 解决方法级别调用时, 当前线程非本插件的ClassLoader注解 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ResolveClassLoader { +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistAllowAutoConfiguration.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistAllowAutoConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..73355f6aeda6787346e026f0d94be6c6d998a4d2 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistAllowAutoConfiguration.java @@ -0,0 +1,60 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.coexist; + +import com.gitee.starblues.utils.ObjectUtils; + +import java.util.HashSet; +import java.util.Set; + +/** + * Coexist模式下存储当前插件允许的 auto 配置 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class CoexistAllowAutoConfiguration { + + private final Set allowPrefix = new HashSet<>(); + + public CoexistAllowAutoConfiguration(){ + addDefault(); + } + + private void addDefault(){ + allowPrefix.add("org.springframework.boot.autoconfigure.aop.AopAutoConfiguration"); + } + + public CoexistAllowAutoConfiguration add(String autoConfigurationClass){ + if(ObjectUtils.isEmpty(autoConfigurationClass)){ + return this; + } + allowPrefix.add(autoConfigurationClass); + return this; + } + + public boolean match(String autoConfigurationClass){ + for (String prefix : allowPrefix) { + if(autoConfigurationClass.startsWith(prefix)){ + return true; + } + } + return false; + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistResolveClassLoaderAspect.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistResolveClassLoaderAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..0d1b1df8b493dd17d4e53cba6f59775b1d05d4ff --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/coexist/CoexistResolveClassLoaderAspect.java @@ -0,0 +1,53 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.coexist; + +import com.gitee.starblues.bootstrap.annotation.ResolveClassLoader; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; + +/** + * Coexist模式下解决调用方法时, 非本插件的ClassLoader + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +@Aspect +public class CoexistResolveClassLoaderAspect { + + @Pointcut("@annotation(com.gitee.starblues.bootstrap.annotation.ResolveClassLoader)") + public void test() { + + } + + @Around("@annotation(resolveClassLoader)") + public Object around(ProceedingJoinPoint pjp, ResolveClassLoader resolveClassLoader) throws Throwable{ + Thread thread = Thread.currentThread(); + ClassLoader oldClassLoader = thread.getContextClassLoader(); + try { + Object target = pjp.getTarget(); + thread.setContextClassLoader(target.getClass().getClassLoader()); + return pjp.proceed(); + } finally { + thread.setContextClassLoader(oldClassLoader); + } + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncher.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..994ecc01ebe73369c45e00c7ff90be5b06c16d18 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncher.java @@ -0,0 +1,38 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.spring.SpringPluginHook; + +/** + * 插件启动器 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public interface BootstrapLauncher { + + /** + * 启动插件 + * @param primarySources 主启动类 + * @param args 启动参数 + * @return SpringPluginHook + */ + SpringPluginHook launch(Class[] primarySources, String[] args); + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncherFactory.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncherFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..bc14d229eacbcd7259274c86781e1e50ff4b38a5 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/BootstrapLauncherFactory.java @@ -0,0 +1,37 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.bootstrap.SpringPluginBootstrap; + +/** + * BootstrapLauncher 创造工厂 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public interface BootstrapLauncherFactory { + + /** + * 创造 BootstrapLauncher + * @param bootstrap SpringPluginBootstrap + * @return BootstrapLauncher + */ + BootstrapLauncher create(SpringPluginBootstrap bootstrap); + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/CoexistBootstrapLauncher.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/CoexistBootstrapLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..59868a6a8a057baee3f5f20cf65a6f4b7712f361 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/CoexistBootstrapLauncher.java @@ -0,0 +1,111 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.bootstrap.*; +import com.gitee.starblues.bootstrap.annotation.AutowiredType; +import com.gitee.starblues.bootstrap.coexist.CoexistResolveClassLoaderAspect; +import com.gitee.starblues.bootstrap.processor.DefaultProcessorContext; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.core.launcher.plugin.PluginInteractive; +import com.gitee.starblues.spring.SpringPluginHook; +import lombok.AllArgsConstructor; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + * Coexist 类型启动器 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + * @see com.gitee.starblues.loader.DevelopmentMode#COEXIST + */ +@AllArgsConstructor +public class CoexistBootstrapLauncher implements BootstrapLauncher{ + + private final SpringPluginBootstrap bootstrap; + private final SpringPluginProcessor pluginProcessor; + private final PluginInteractive pluginInteractive; + + @Override + public SpringPluginHook launch(Class[] primarySources, String[] args) { + ProcessorContext processorContext = new DefaultProcessorContext( + bootstrap.getRunMode(), bootstrap, pluginInteractive, bootstrap.getClass() + ); + SpringApplication springApplication = new CoexistSpringApplication( + pluginProcessor, + processorContext, + primarySources); + springApplication.run(args); + return new DefaultSpringPluginHook(pluginProcessor, processorContext); + } + + private static class CoexistSpringApplication extends PluginSpringApplication{ + + public CoexistSpringApplication(SpringPluginProcessor pluginProcessor, ProcessorContext processorContext, Class... primarySources) { + super(pluginProcessor, processorContext, primarySources); + } + + @Override + protected DefaultListableBeanFactory getBeanFactory(ProcessorContext processorContext) { + return new CoexistPluginListableBeanFactory(processorContext); + } + + @Override + protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { + super.configureEnvironment(environment, args); + } + + @Override + protected GenericApplicationContext getApplicationContext() { + PluginApplicationContext applicationContext = (PluginApplicationContext) super.getApplicationContext(); + applicationContext.register(CoexistResolveClassLoaderAspect.class); + return applicationContext; + } + } + + private static class CoexistPluginListableBeanFactory extends PluginListableBeanFactory{ + + public CoexistPluginListableBeanFactory(ProcessorContext processorContext) { + super(processorContext); + } + + @Override + protected AutowiredTypeResolver getAutowiredTypeResolver(ProcessorContext processorContext) { + return new CoexistAutowiredTypeResolver(); + } + } + + private static class CoexistAutowiredTypeResolver implements AutowiredTypeResolver{ + + @Override + public AutowiredType.Type resolve(DependencyDescriptor descriptor) { + AutowiredType autowiredType = descriptor.getAnnotation(AutowiredType.class); + if(autowiredType != null){ + return autowiredType.value(); + } else { + return AutowiredType.Type.PLUGIN; + } + } + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/DefaultBootstrapLauncherFactory.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/DefaultBootstrapLauncherFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..5fb5cef7ea821a2cc32aad2903f5e93885074f73 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/DefaultBootstrapLauncherFactory.java @@ -0,0 +1,55 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.bootstrap.PluginDisableAutoConfiguration; +import com.gitee.starblues.bootstrap.SpringPluginBootstrap; +import com.gitee.starblues.bootstrap.processor.ComposeSpringPluginProcessor; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.core.launcher.plugin.PluginInteractive; +import com.gitee.starblues.loader.launcher.DevelopmentModeSetting; + +import java.util.List; + +/** + * 默认的 BootstrapLauncher 创造工厂 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class DefaultBootstrapLauncherFactory implements BootstrapLauncherFactory{ + @Override + public BootstrapLauncher create(SpringPluginBootstrap bootstrap) { + PluginDisableAutoConfiguration.setLaunchPlugin(); + ProcessorContext.RunMode runMode = bootstrap.getRunMode(); + List customPluginProcessors = bootstrap.getCustomPluginProcessors(); + PluginInteractive pluginInteractive = bootstrap.getPluginInteractive(); + + SpringPluginProcessor pluginProcessor = new ComposeSpringPluginProcessor(runMode, customPluginProcessors); + BootstrapLauncher bootstrapLauncher = null; + if(DevelopmentModeSetting.isolation()){ + bootstrapLauncher = new IsolationBootstrapLauncher(bootstrap, pluginProcessor, pluginInteractive); + } else if(DevelopmentModeSetting.coexist()){ + bootstrapLauncher = new CoexistBootstrapLauncher(bootstrap, pluginProcessor, pluginInteractive); + } else { + bootstrapLauncher = new OneselfBootstrapLauncher(bootstrap, pluginProcessor, pluginInteractive); + } + return bootstrapLauncher; + } +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/IsolationBootstrapLauncher.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/IsolationBootstrapLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..661844390f051fdf33d84637c2de42e5a6f0def2 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/IsolationBootstrapLauncher.java @@ -0,0 +1,59 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.bootstrap.DefaultSpringPluginHook; +import com.gitee.starblues.bootstrap.PluginSpringApplication; +import com.gitee.starblues.bootstrap.SpringPluginBootstrap; +import com.gitee.starblues.bootstrap.processor.DefaultProcessorContext; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.core.launcher.plugin.PluginInteractive; +import com.gitee.starblues.spring.SpringPluginHook; +import lombok.AllArgsConstructor; +import org.springframework.boot.SpringApplication; + +/** + * isolation 模式插件启动器 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + * @see com.gitee.starblues.loader.DevelopmentMode#ISOLATION + */ +@AllArgsConstructor +public class IsolationBootstrapLauncher implements BootstrapLauncher{ + + private final SpringPluginBootstrap bootstrap; + private final SpringPluginProcessor pluginProcessor; + private final PluginInteractive pluginInteractive; + + @Override + public SpringPluginHook launch(Class[] primarySources, String[] args) { + ProcessorContext.RunMode runMode = bootstrap.getRunMode(); + + ProcessorContext processorContext = new DefaultProcessorContext( + runMode, bootstrap, pluginInteractive, bootstrap.getClass() + ); + SpringApplication springApplication = new PluginSpringApplication( + pluginProcessor, + processorContext, + primarySources); + springApplication.run(args); + return new DefaultSpringPluginHook(pluginProcessor, processorContext); + } +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/OneselfBootstrapLauncher.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/OneselfBootstrapLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..d0f4dcdac12f90bc4d2c3fa630996ba7d6674e70 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/launcher/OneselfBootstrapLauncher.java @@ -0,0 +1,47 @@ +package com.gitee.starblues.bootstrap.launcher; + +import com.gitee.starblues.bootstrap.DefaultSpringPluginHook; +import com.gitee.starblues.bootstrap.PluginOneselfSpringApplication; +import com.gitee.starblues.bootstrap.PluginSpringApplication; +import com.gitee.starblues.bootstrap.SpringPluginBootstrap; +import com.gitee.starblues.bootstrap.processor.DefaultProcessorContext; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.core.launcher.plugin.PluginInteractive; +import com.gitee.starblues.spring.SpringPluginHook; +import lombok.AllArgsConstructor; +import org.springframework.boot.SpringApplication; + +/** + * 插件自主启动配置 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +@AllArgsConstructor +public class OneselfBootstrapLauncher implements BootstrapLauncher{ + + private final SpringPluginBootstrap bootstrap; + private final SpringPluginProcessor pluginProcessor; + private final PluginInteractive pluginInteractive; + + + @Override + public SpringPluginHook launch(Class[] primarySources, String[] args) { + ProcessorContext.RunMode runMode = bootstrap.getRunMode(); + + ProcessorContext processorContext = new DefaultProcessorContext( + runMode, bootstrap, pluginInteractive, bootstrap.getClass() + ); + SpringApplication springApplication = new PluginOneselfSpringApplication( + pluginProcessor, + processorContext, + primarySources); + springApplication.run(args); + return new DefaultSpringPluginHook(pluginProcessor, processorContext); + } + + + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ComposeSpringPluginProcessor.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ComposeSpringPluginProcessor.java index 63e7911341c4a2154db9d88ba65842c04a5d4015..c21dc112733924b7e54964e9235b6e97bf0d4af9 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ComposeSpringPluginProcessor.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ComposeSpringPluginProcessor.java @@ -18,6 +18,7 @@ package com.gitee.starblues.bootstrap.processor; import com.gitee.starblues.bootstrap.SpringPluginBootstrap; import com.gitee.starblues.bootstrap.annotation.DisablePluginWeb; +import com.gitee.starblues.bootstrap.processor.oneself.OneselfProcessor; import com.gitee.starblues.bootstrap.processor.web.PluginControllerProcessor; import com.gitee.starblues.bootstrap.processor.web.PluginInterceptorsProcessor; import com.gitee.starblues.bootstrap.processor.web.PluginSpringDocControllerProcessor; @@ -72,6 +73,7 @@ public class ComposeSpringPluginProcessor implements SpringPluginProcessor { List processors = new ArrayList<>(); addDefaultProcessors(context, processors); addDefaultWebEnvProcessors(context, processors); + addOneselfProcessors(context, processors); processors.addAll(this.processors); this.processors = processors.stream() .filter(p->{ @@ -178,6 +180,15 @@ public class ComposeSpringPluginProcessor implements SpringPluginProcessor { ProcessorUtils.add(processors, PluginSpringDocControllerProcessor::new); } + /** + * 添加 Oneself 模式处理者 + * @param context ProcessorContext + * @param processors 处理者容器集合 + */ + private void addOneselfProcessors(ProcessorContext context, List processors) { + processors.add(new OneselfProcessor()); + } + private void processException(SpringPluginProcessor processor, String executeType, Throwable e, boolean isThrow) throws ProcessorException{ String error = "Processor[" + processor.getClass().getName() + "] execute[" + executeType + "] failure : " diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/DefaultProcessorContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/DefaultProcessorContext.java index d0801cc961327e0ac7d1c5ca04f81a5a9cce6375..8867f9083ebec9904859b42d0d6a5d9472750882 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/DefaultProcessorContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/DefaultProcessorContext.java @@ -17,6 +17,7 @@ package com.gitee.starblues.bootstrap.processor; import com.gitee.starblues.bootstrap.SpringPluginBootstrap; +import com.gitee.starblues.core.PluginInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.launcher.plugin.CacheRegistryInfo; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; @@ -82,6 +83,11 @@ public class DefaultProcessorContext extends CacheRegistryInfo implements Proces return pluginInteractive.getPluginDescriptor(); } + @Override + public PluginInfo getPluginInfo() { + return pluginInteractive.getPluginInsideInfo(); + } + @Override public Class getRunnerClass() { return runnerClass; diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/FrameDefineBeanProcessor.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/FrameDefineBeanProcessor.java index ddbb7b8fafdb53c4fff23c623e33252e9fe665e9..5098ffc933ff2723687abc2eab20c7cda4853661 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/FrameDefineBeanProcessor.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/FrameDefineBeanProcessor.java @@ -36,6 +36,7 @@ public class FrameDefineBeanProcessor implements SpringPluginProcessor { InsidePluginDescriptor pluginDescriptor = context.getPluginDescriptor(); ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory(); beanFactory.registerSingleton("pluginDescriptor", pluginDescriptor.toPluginDescriptor()); + beanFactory.registerSingleton("pluginInfo", context.getPluginInfo()); beanFactory.registerSingleton("mainApplicationContext", context.getMainApplicationContext()); } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ProcessorContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ProcessorContext.java index 42cec5b55f5ed4a9e55a0ae6f1f09e1cf8140d77..d7aba0235f3690610abc06aba649194da93e222e 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ProcessorContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/ProcessorContext.java @@ -18,6 +18,7 @@ package com.gitee.starblues.bootstrap.processor; import com.gitee.starblues.bootstrap.SpringPluginBootstrap; +import com.gitee.starblues.core.PluginInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; import com.gitee.starblues.core.launcher.plugin.RegistryInfo; @@ -54,6 +55,12 @@ public interface ProcessorContext extends RegistryInfo { */ InsidePluginDescriptor getPluginDescriptor(); + /** + * 得到插件信息 PluginInfo + * @return PluginInfo + */ + PluginInfo getPluginInfo(); + /** * 得到启动的class类 * @return Class diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/SpringPluginProcessor.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/SpringPluginProcessor.java index 5b959466a634992bf46841e763802787994b284e..ce593214bedc1ca9ead1a56cab218cdd213d28b0 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/SpringPluginProcessor.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/SpringPluginProcessor.java @@ -26,6 +26,7 @@ import com.gitee.starblues.utils.OrderPriority; */ public interface SpringPluginProcessor extends Order { + /** * 初始化时 * @param context ProcessorContext diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigureMainPluginEnvironment.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/ConfigureMainPluginEnvironment.java similarity index 92% rename from spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigureMainPluginEnvironment.java rename to spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/ConfigureMainPluginEnvironment.java index 912f2546cda5c555de6622fedaf650c596209b32..0471be38243a001a6d68898f1ed27f3b1e7ee705 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ConfigureMainPluginEnvironment.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/ConfigureMainPluginEnvironment.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.gitee.starblues.bootstrap; +package com.gitee.starblues.bootstrap.processor.oneself; +import com.gitee.starblues.bootstrap.SpringPluginBootstrap; import com.gitee.starblues.bootstrap.annotation.OneselfConfig; import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.bootstrap.utils.AnnotationUtils; @@ -41,12 +42,12 @@ import java.util.*; * @version 3.0.0 * @since 3.0.0 */ -class ConfigureMainPluginEnvironment { +public class ConfigureMainPluginEnvironment { private final ProcessorContext processorContext; private final List propertySourceLoaders; - ConfigureMainPluginEnvironment(ProcessorContext processorContext) { + public ConfigureMainPluginEnvironment(ProcessorContext processorContext) { this.processorContext = processorContext; this.propertySourceLoaders = new ArrayList<>(2); @@ -54,7 +55,7 @@ class ConfigureMainPluginEnvironment { this.propertySourceLoaders.add(new PropertiesPropertySourceLoader()); } - void configureEnvironment(ConfigurableEnvironment environment, String[] args) { + public void configureEnvironment(ConfigurableEnvironment environment, String[] args) { SpringPluginBootstrap springPluginBootstrap = processorContext.getSpringPluginBootstrap(); OneselfConfig oneselfConfig = AnnotationUtils.findAnnotation(springPluginBootstrap.getClass(), OneselfConfig.class); @@ -104,5 +105,4 @@ class ConfigureMainPluginEnvironment { throw new RuntimeException(e); } } - } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/OneselfProcessor.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/OneselfProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..f320f7c44ee25c95f8728af05bb3b933677d0af3 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/oneself/OneselfProcessor.java @@ -0,0 +1,54 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.bootstrap.processor.oneself; + +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.processor.ProcessorException; +import com.gitee.starblues.bootstrap.processor.SpringPluginProcessor; +import com.gitee.starblues.integration.operator.EmptyPluginOperator; +import com.gitee.starblues.integration.user.DefaultPluginUser; +import com.gitee.starblues.spring.extract.DefaultOpExtractFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.support.GenericApplicationContext; + +/** + * 子启动处理器 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class OneselfProcessor implements SpringPluginProcessor { + + @Override + public void initialize(ProcessorContext context) throws ProcessorException { + registerMainBean(context.getApplicationContext()); + } + + @Override + public ProcessorContext.RunMode runMode() { + return ProcessorContext.RunMode.ONESELF; + } + + private void registerMainBean(GenericApplicationContext applicationContext){ + DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory(); + beanFactory.registerSingleton("extractFactory", new DefaultOpExtractFactory()); + beanFactory.registerSingleton("pluginUser", new DefaultPluginUser(applicationContext)); + beanFactory.registerSingleton("pluginOperator", new EmptyPluginOperator()); + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/web/PluginControllerProcessor.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/web/PluginControllerProcessor.java index 3840ab5a18aa3ac08b84ff2b4bfbabe2ac7f4f87..bfba726100dcbd1126f18933ee79ef81ed507005 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/web/PluginControllerProcessor.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/processor/web/PluginControllerProcessor.java @@ -81,8 +81,8 @@ public class PluginControllerProcessor implements SpringPluginProcessor { return; } GenericApplicationContext applicationContext = processorContext.getApplicationContext(); - applicationContext.registerBean("pluginControllerPostProcessor", - ControllerPostProcessor.class, ()-> new ControllerPostProcessor(processorContext)); + applicationContext.getDefaultListableBeanFactory() + .addBeanPostProcessor(new ControllerPostProcessor(processorContext)); } @Override diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/PluginCloseListener.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/PluginCloseListener.java index 7942eae37c9c9f42b603a55986275809fabe734f..c151abfcfcea9979024c050d22759ea440b34c66 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/PluginCloseListener.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/PluginCloseListener.java @@ -16,20 +16,37 @@ package com.gitee.starblues.bootstrap.realize; +import com.gitee.starblues.core.PluginCloseType; +import com.gitee.starblues.core.PluginInfo; import com.gitee.starblues.core.descriptor.PluginDescriptor; +import org.springframework.context.support.GenericApplicationContext; /** * 插件被停止监听者。用于自定义关闭资源 * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.0 */ public interface PluginCloseListener { /** * 关闭时调用 * @param descriptor 当前插件描述者 + * @deprecated 在 3.1.1 版本会被删除 + * @since 3.0.0 */ - void close(PluginDescriptor descriptor); + default void close(PluginDescriptor descriptor){} + + /** + * 关闭时调用 + * @param applicationContext 当前插件的ApplicationContext + * @param pluginInfo 当前插件信息 + * @param closeType 停止类型 + * @since 3.1.0 + */ + default void close(GenericApplicationContext applicationContext, + PluginInfo pluginInfo, PluginCloseType closeType){ + close(pluginInfo != null ? pluginInfo.getPluginDescriptor() : null); + } } diff --git a/spring-brick-common/pom.xml b/spring-brick-common/pom.xml index 98f6c3650c6305b1494d167822473b5179668c2c..3a57ab0afeab6b19d93eaacd640f1e78c2f3890a 100644 --- a/spring-brick-common/pom.xml +++ b/spring-brick-common/pom.xml @@ -7,7 +7,7 @@ spring-brick-parent com.gitee.starblues - 3.0.3 + 3.1.0 spring-brick-common diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/Constants.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/Constants.java index 2151f6cc2a0eb2bd4c0cbf6dec752b41500c1cb4..481b524d2f5180a2abc6736b6761b17746fc1720 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/common/Constants.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/Constants.java @@ -16,6 +16,8 @@ package com.gitee.starblues.common; +import java.io.File; + /** * 静态常量 * @author starBlues diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/ManifestKey.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/ManifestKey.java index b4ffd0958ed1f7bfcc76e4395842addbc04c36ff..c4b25f9812565cc755be85f1f00c183ea9c3e14d 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/common/ManifestKey.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/ManifestKey.java @@ -83,6 +83,22 @@ public class ManifestKey { */ public static final String MAIN_PACKAGE_TYPE = "Main-Package-Type"; + /** + * jar main development mode + */ + public static final String DEVELOPMENT_MODE = "Development-Mode"; + + /** + * jar package name + */ + public static final String IMPLEMENTATION_TITLE = "Implementation-Title"; + + /** + * jar package version + */ + public static final String IMPLEMENTATION_VERSION = "Implementation-Version"; + + /** * 获取值 * diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/PluginDisableAutoConfig.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/PluginDisableAutoConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..24bdefef3edefd79cc52a1e3a3f5f548e4769a78 --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/PluginDisableAutoConfig.java @@ -0,0 +1,25 @@ +package com.gitee.starblues.common; + +import java.util.HashSet; +import java.util.Set; + +/** + * 插件禁用的 AutoConfiguration 配置 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class PluginDisableAutoConfig { + + private final static Set COMMON_PLUGIN_DISABLE_AUTO_CONFIG = new HashSet<>(); + + + static { + COMMON_PLUGIN_DISABLE_AUTO_CONFIG.add("com.gitee.starblues.integration.SpringBootPluginStarter"); + } + + public static Set getCommonPluginDisableAutoConfig() { + return COMMON_PLUGIN_DISABLE_AUTO_CONFIG; + } +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java index 34b06d33ba6ada2cc2a8570745c77fe5cdfd992b..a057e15315fe473cfbe229a9506dab30de48e5c1 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java @@ -17,6 +17,7 @@ package com.gitee.starblues.utils; import com.gitee.starblues.common.Constants; +import com.gitee.starblues.common.PackageStructure; import java.io.File; import java.io.IOException; @@ -25,7 +26,8 @@ import java.io.IOException; * 文件工具类 * * @author starBlues - * @version 3.0.2 + * @since 3.0.0 + * @version 3.1.0 */ public class FilesUtils { @@ -43,14 +45,69 @@ public class FilesUtils { return null; } + /** + * 是否存在文件 + * @param path 文件路径 + * @return boolean + */ + public static boolean existFile(String path){ + if(ObjectUtils.isEmpty(path)){ + return false; + } + return new File(path).exists(); + } + /** * 拼接file路径 * * @param paths 拼接的路径 * @return 拼接的路径 + * @since 3.0.0 */ - public static String joiningFilePath(String ...paths){ + public static String joiningFilePath(String ...paths) { + if (paths == null || paths.length == 0) { + return ""; + } + StringBuilder stringBuilder = new StringBuilder(); + int length = paths.length; + for (int i = 0; i < length; i++) { + String path = paths[i]; + if (ObjectUtils.isEmpty(path)) { + continue; + } + if (i < length - 1) { + if (path.endsWith("/")) { + path = path.replace("/", ""); + } else if (path.endsWith("\\")) { + path = path.replace("\\", ""); + } else if (path.endsWith("//")) { + path = path.replace("//", ""); + } + } + if (i > 0) { + if (path.startsWith(File.separator) || path.startsWith("/") || + path.startsWith("\\") || path.startsWith("//")) { + stringBuilder.append(path); + } else { + stringBuilder.append(File.separator).append(path); + } + } else { + stringBuilder.append(path); + } + } + + return stringBuilder.toString(); + } + + /** + * 拼接 zip /jar 路径 + * + * @param paths 拼接的路径 + * @return 拼接的路径 + * @since 3.1.0 + */ + public static String joiningZipPath(String ...paths){ if(paths == null || paths.length == 0){ return ""; } @@ -61,12 +118,20 @@ public class FilesUtils { if(ObjectUtils.isEmpty(path)) { continue; } + if(i < length - 1){ + if(path.endsWith("/")){ + path = path.replace("/", ""); + } else if(path.endsWith("\\")){ + path = path.replace("\\", ""); + } else if(path.endsWith("//")){ + path = path.replace("//", ""); + } + } if(i > 0){ - if(path.startsWith(File.separator) || path.startsWith("/") || - path.startsWith("\\") || path.startsWith("//")){ + if(path.startsWith(PackageStructure.SEPARATOR)){ stringBuilder.append(path); } else { - stringBuilder.append(File.separator).append(path); + stringBuilder.append(PackageStructure.SEPARATOR).append(path); } } else { stringBuilder.append(path); @@ -79,6 +144,9 @@ public class FilesUtils { public static File createFile(String path) throws IOException { try { File file = new File(path); + if(file.exists()){ + return file; + } File parentFile = file.getParentFile(); if(!parentFile.exists()){ if(!parentFile.mkdirs()){ diff --git a/spring-brick-loader/pom.xml b/spring-brick-loader/pom.xml index 2b61cd0496b8caaf31f9447d8a11986ca39c1b99..d453dab0cf4a460326c4600bf42576df9d27f2df 100644 --- a/spring-brick-loader/pom.xml +++ b/spring-brick-loader/pom.xml @@ -5,7 +5,7 @@ spring-brick-parent com.gitee.starblues - 3.0.3 + 3.1.0 4.0.0 diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/DevelopmentMode.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/DevelopmentMode.java new file mode 100644 index 0000000000000000000000000000000000000000..82d0029b426daed0a1d1d19ecd040fd337cec99c --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/DevelopmentMode.java @@ -0,0 +1,38 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader; + +/** + * 开发模式key定义 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public abstract class DevelopmentMode { + + /** + * 隔离模式 + */ + public static final String ISOLATION = "isolation"; + + /** + * 共存模式 + */ + public static final String COEXIST = "coexist"; + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/LoaderConstant.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/LoaderConstant.java index 4631f5566c84a77a096a8897f266b64dc9652614..94f65c44261b96653694d1cebec20b9fcb495d72 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/LoaderConstant.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/LoaderConstant.java @@ -42,6 +42,7 @@ public class LoaderConstant { public static final String MAIN_LIB_INDEXES_SPLIT = " "; public static final String START_CLASS = "Start-Class"; + public static final String MAIN_DEVELOPMENT_MODE = "Development-Mode"; public static final String MAIN_PACKAGE_TYPE = "Main-Package-Type"; public static final String MAIN_PACKAGE_TYPE_JAR = "jar"; diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java index 056596aa54aad24897b4535cbaedd80367e45f7f..c32edec64e966c5b5a9a63707410e49191e888a8 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java @@ -143,6 +143,12 @@ public class PluginResourceStorage { IOUtils.closeQuietly(jarFile); } } + for (JarFile jarFile : rootJarFileMap.values()) { + if(jarFile == null){ + continue; + } + IOUtils.closeQuietly(jarFile); + } jarFileMap.clear(); rootJarFileMap.clear(); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/Archive.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/Archive.java index 50bdc2c82e8090145c09c247b1e477242fa64bfc..8c351afdde32cb6e50257858c150a7a435ff9a4f 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/Archive.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/Archive.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -25,8 +26,11 @@ import java.util.jar.Manifest; /** * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * An archive that can be launched by the {@link Launcher}. + * + * @author Phillip Webb + * @since 1.0.0 + * @see JarFileArchive */ public interface Archive extends Iterable, AutoCloseable { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/ExplodedArchive.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/ExplodedArchive.java index 284a2700716deeda6ab2e2d44e9d677c943ac6d4..7ec7f0338fb87e0797e87e2d9e033ff82deca92b 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/ExplodedArchive.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/ExplodedArchive.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -26,9 +27,12 @@ import java.util.*; import java.util.jar.Manifest; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link Archive} implementation backed by an exploded archive directory. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Madhura Bhave + * @since 1.0.0 */ public class ExplodedArchive implements Archive { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/JarFileArchive.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/JarFileArchive.java index 8698a2ef9e78c4f467f34fd4d3bbd344b3d27fe8..1183476ecf540dea569a583afd8ebcf5c25ddbab 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/JarFileArchive.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/archive/JarFileArchive.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -35,9 +36,11 @@ import java.util.jar.JarEntry; import java.util.jar.Manifest; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link Archive} implementation backed by a {@link JarFile}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @since 1.0.0 */ public class JarFileArchive implements Archive { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/ClassLoaderTranslator.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/ClassLoaderTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..3030b1708c00ec1f5a135589f91fb69425719110 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/ClassLoaderTranslator.java @@ -0,0 +1,127 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.classloader; + +import com.gitee.starblues.loader.classloader.resource.Resource; +import com.gitee.starblues.loader.classloader.resource.loader.DefaultResource; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoader; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +/** + * classloader 转换器 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class ClassLoaderTranslator implements ResourceLoaderFactory { + + private final URLClassLoader classLoader; + + public ClassLoaderTranslator(URLClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public void addResource(String path) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public void addResource(File file) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public void addResource(Path path) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public void addResource(URL url) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public void addResource(Resource resource) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public void addResource(ResourceLoader resourceLoader) throws Exception { + throw new RuntimeException("Does not support!"); + } + + @Override + public Resource findFirstResource(String name) { + URL url = classLoader.getResource(name); + if(url == null){ + return null; + } + return new DefaultResource(name, url, url); + } + + @Override + public Enumeration findAllResource(String name) { + try { + Enumeration resources = classLoader.getResources(name); + return new Enumeration() { + @Override + public boolean hasMoreElements() { + return resources.hasMoreElements(); + } + + @Override + public Resource nextElement() { + URL url = resources.nextElement(); + if(url == null){ + return null; + } + return new DefaultResource(name, url, url); + } + }; + } catch (IOException e) { + return Collections.emptyEnumeration(); + } + } + + @Override + public InputStream getInputStream(String name) { + return classLoader.getResourceAsStream(name); + } + + @Override + public List getUrls() { + return Arrays.asList(classLoader.getURLs()); + } + + @Override + public void close() throws Exception { + + } +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GeneralUrlClassLoader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GeneralUrlClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..c7a07e61651eaf606fcb82521c0774ce0d1452b4 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GeneralUrlClassLoader.java @@ -0,0 +1,111 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.classloader; + +import com.gitee.starblues.loader.classloader.resource.Resource; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoader; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; +import com.gitee.starblues.loader.classloader.resource.storage.EmptyResourceStorage; +import com.gitee.starblues.loader.classloader.resource.storage.ResourceStorage; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Enumeration; +import java.util.List; + +/** + * 通用的Url ClassLoader + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class GeneralUrlClassLoader extends URLClassLoader implements ResourceLoaderFactory { + + private final String name; + private final ResourceLoaderFactory classLoaderTranslator; + + private final ResourceStorage resourceStorage = new EmptyResourceStorage(); + + public GeneralUrlClassLoader(String name, ClassLoader parent) { + super(new URL[]{}, parent); + this.name = name; + this.classLoaderTranslator = new ClassLoaderTranslator(this); + } + + public String getName() { + return name; + } + + @Override + public void addResource(String path) throws Exception { + addResource(Paths.get(path)); + } + + @Override + public void addResource(File file) throws Exception { + if(!file.exists()){ + throw new FileNotFoundException("Not found file:" + file.getPath()); + } + addURL(file.toPath().toUri().toURL()); + } + + @Override + public void addResource(Path path) throws Exception { + addResource(path.toFile()); + } + + @Override + public void addResource(URL url) throws Exception { + super.addURL(url); + } + + @Override + public void addResource(Resource resource) throws Exception { + addResource(resource.getUrl()); + } + + @Override + public void addResource(ResourceLoader resourceLoader) throws Exception { + resourceLoader.load(resourceStorage); + } + + @Override + public Resource findFirstResource(String name) { + return classLoaderTranslator.findFirstResource(name); + } + + @Override + public Enumeration findAllResource(String name) { + return classLoaderTranslator.findAllResource(name); + } + + @Override + public InputStream getInputStream(String name) { + return classLoaderTranslator.getInputStream(name); + } + + @Override + public List getUrls() { + return classLoaderTranslator.getUrls(); + } +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GenericClassLoader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GenericClassLoader.java index fe1a01fd44b9f04184c142138e930f800bd1fa58..a186c847774530ef36bbc8ed78c3cdd4dc36d773 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GenericClassLoader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/GenericClassLoader.java @@ -27,24 +27,21 @@ import java.io.*; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Path; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.*; /** * 基本的 ClassLoader * @author starBlues * @version 3.0.0 */ -public class GenericClassLoader extends URLClassLoader { +public class GenericClassLoader extends URLClassLoader implements ResourceLoaderFactory{ private final String name; private final ClassLoader parent; protected final ResourceLoaderFactory resourceLoaderFactory; - private final Map> pluginClassCache = new ConcurrentHashMap<>(); + private final ResourceLoaderFactory classLoaderTranslator; public GenericClassLoader(String name, ResourceLoaderFactory resourceLoaderFactory) { this(name, null, resourceLoaderFactory); @@ -55,36 +52,61 @@ public class GenericClassLoader extends URLClassLoader { this.name = Assert.isNotEmpty(name, "name 不能为空"); this.resourceLoaderFactory = Assert.isNotNull(resourceLoaderFactory, "resourceLoaderFactory 不能为空"); this.parent = parent; - + this.classLoaderTranslator = new ClassLoaderTranslator(this); } public String getName() { return name; } - + @Override public void addResource(String path) throws Exception { resourceLoaderFactory.addResource(path); } + @Override public void addResource(File file) throws Exception { resourceLoaderFactory.addResource(file); } + @Override public void addResource(Path path) throws Exception { resourceLoaderFactory.addResource(path); } + @Override public void addResource(URL url) throws Exception { resourceLoaderFactory.addResource(url); } + @Override + public void addResource(Resource resource) throws Exception { + resourceLoaderFactory.addResource(resource); + } + + @Override public void addResource(ResourceLoader resourceLoader) throws Exception{ resourceLoaderFactory.addResource(resourceLoader); } - public ClassLoader getParentClassLoader(){ - return parent; + @Override + public Resource findFirstResource(String name) { + return classLoaderTranslator.findFirstResource(name); + } + + @Override + public Enumeration findAllResource(String name) { + return classLoaderTranslator.findAllResource(name); + } + + @Override + public InputStream getInputStream(String name) { + return classLoaderTranslator.getInputStream(name); + } + + @Override + public List getUrls() { + return classLoaderTranslator.getUrls(); } @Override @@ -125,11 +147,7 @@ public class GenericClassLoader extends URLClassLoader { protected Class findClassFromLocal(String name) { Class aClass; String formatClassName = formatClassName(name); - aClass = pluginClassCache.get(formatClassName); - if (aClass != null) { - return aClass; - } - Resource resource = resourceLoaderFactory.findResource(formatClassName); + Resource resource = resourceLoaderFactory.findFirstResource(formatClassName); byte[] bytes = null; if(resource != null){ bytes = resource.getBytes(); @@ -140,17 +158,16 @@ public class GenericClassLoader extends URLClassLoader { if(bytes == null || bytes.length == 0){ return null; } - aClass = defineClass(name, bytes, 0, bytes.length ); + aClass = super.defineClass(name, bytes, 0, bytes.length ); if(aClass == null) { return null; } if (aClass.getPackage() == null) { int lastDotIndex = name.lastIndexOf( '.' ); String packageName = (lastDotIndex >= 0) ? name.substring( 0, lastDotIndex) : ""; - definePackage(packageName, null, null, null, + super.definePackage(packageName, null, null, null, null, null, null, null ); } - pluginClassCache.put(name, aClass); return aClass; } @@ -159,13 +176,20 @@ public class GenericClassLoader extends URLClassLoader { if(inputStream == null){ return null; } + ByteArrayOutputStream output = new ByteArrayOutputStream(); try { - return IOUtils.read(inputStream); + byte[] buffer = new byte[4096]; + int n = 0; + while (-1 != (n = inputStream.read(buffer))) { + output.write(buffer, 0, n); + } + return output.toByteArray(); } catch (Exception e){ e.printStackTrace(); return null; } finally { IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(output); } } @@ -218,7 +242,7 @@ public class GenericClassLoader extends URLClassLoader { } protected URL findResourceFromLocal(String name) { - Resource resource = resourceLoaderFactory.findResource(name); + Resource resource = resourceLoaderFactory.findFirstResource(name); if (resource == null) { return null; } @@ -262,7 +286,7 @@ public class GenericClassLoader extends URLClassLoader { } protected Enumeration findResourcesFromLocal(String name) throws IOException{ - Enumeration enumeration = resourceLoaderFactory.findResources(name); + Enumeration enumeration = resourceLoaderFactory.findAllResource(name); return new Enumeration() { @Override public boolean hasMoreElements() { @@ -278,10 +302,8 @@ public class GenericClassLoader extends URLClassLoader { @Override public void close() throws IOException { - synchronized (pluginClassCache){ - pluginClassCache.clear(); - IOUtils.closeQuietly(resourceLoaderFactory); - } + super.close(); + IOUtils.closeQuietly(resourceLoaderFactory); } private String formatResourceName(String name) { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/Resource.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/Resource.java index 59ea855bebf24b38c1177af0c0545541a754ed2a..a2c4d0132075b744d186d22f2d249a70a3d1974e 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/Resource.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/Resource.java @@ -54,6 +54,7 @@ public interface Resource extends AutoCloseable{ /** * 设置字节数 * @param byteGetter byteGetter + * @throws Exception set byte 异常 */ void setBytes(ResourceByteGetter byteGetter) throws Exception; diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/AbstractResourceLoader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/AbstractResourceLoader.java index 67d1a918acac4096644cee9aa5fc2d41dc47e538..b3ec9ecd2e394120d638ec2a3c1af95bb6cc1e36 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/AbstractResourceLoader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/AbstractResourceLoader.java @@ -16,7 +16,6 @@ package com.gitee.starblues.loader.classloader.resource.loader; - import com.gitee.starblues.loader.classloader.resource.storage.ResourceStorage; import com.gitee.starblues.loader.utils.IOUtils; @@ -66,6 +65,7 @@ public abstract class AbstractResourceLoader implements ResourceLoader{ /** * 子类初始化实现 + * @param resourceStorage 资源存储 * @throws Exception 初始异常 */ protected abstract void loadOfChild(ResourceStorage resourceStorage) throws Exception; diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/DefaultResourceLoaderFactory.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/DefaultResourceLoaderFactory.java index e853705698cef3b9ccbe7f63545153e8223c9e40..566652169dd685977bcd4e9ac2a60572f1530199 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/DefaultResourceLoaderFactory.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/DefaultResourceLoaderFactory.java @@ -19,24 +19,18 @@ package com.gitee.starblues.loader.classloader.resource.loader; import com.gitee.starblues.loader.classloader.resource.Resource; import com.gitee.starblues.loader.classloader.resource.storage.ResourceStorage; import com.gitee.starblues.loader.classloader.resource.storage.SameRootResourceStorage; -import com.gitee.starblues.loader.launcher.ResourceLoaderFactoryGetter; +import com.gitee.starblues.loader.launcher.isolation.ResourceLoaderFactoryGetter; import com.gitee.starblues.loader.utils.IOUtils; import com.gitee.starblues.loader.utils.ResourceUtils; import java.io.File; -import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; -import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; -import java.util.function.Function; /** * 默认的资源加载工厂 @@ -102,24 +96,34 @@ public class DefaultResourceLoaderFactory implements ResourceLoaderFactory{ } @Override - public void addResource(ResourceLoader resourceLoader) throws Exception { - if(resourceLoader == null){ - return; + public void addResource(Resource resource) throws Exception { + SameRootResourceStorage resourceStorage = resourceLoaderMap.get(resource.getBaseUrl()); + if (resourceStorage == null) { + resourceStorage = ResourceLoaderFactoryGetter.getResourceStorage( + classLoaderName, + resource.getBaseUrl()); + resourceLoaderMap.put(resource.getBaseUrl(), resourceStorage); } - if (resourceLoaderMap.containsKey(resourceLoader.getBaseUrl())) { + resourceStorage.add(resource.getName(), resource.getUrl(), resource::getBytes); + } + + @Override + public synchronized void addResource(ResourceLoader resourceLoader) throws Exception { + if(resourceLoader == null){ return; } - SameRootResourceStorage resourceStorage = ResourceLoaderFactoryGetter.getResourceStorage( - classLoaderName, - resourceLoader.getBaseUrl()); - resourceLoader.load(resourceStorage); - if(!resourceStorage.isEmpty()){ + SameRootResourceStorage resourceStorage = resourceLoaderMap.get(resourceLoader.getBaseUrl()); + if (resourceStorage == null) { + resourceStorage = ResourceLoaderFactoryGetter.getResourceStorage( + classLoaderName, + resourceLoader.getBaseUrl()); resourceLoaderMap.put(resourceLoader.getBaseUrl(), resourceStorage); } + resourceLoader.load(resourceStorage); } @Override - public Resource findResource(String name) { + public Resource findFirstResource(String name) { for (Map.Entry entry : resourceLoaderMap.entrySet()) { ResourceStorage resourceStorage = entry.getValue(); Resource resource = resourceStorage.get(name); @@ -131,7 +135,7 @@ public class DefaultResourceLoaderFactory implements ResourceLoaderFactory{ } @Override - public Enumeration findResources(String name) { + public Enumeration findAllResource(String name) { return new Enumeration() { private final List list = new ArrayList<>(resourceLoaderMap.values()); private int index = 0; diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoader.java index 819aff85567f538ad4df6af0404876f8b078c78c..7b722d740325b39c17cbb3d4ec75c812d3c53cda 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoader.java @@ -28,8 +28,18 @@ import java.net.URL; */ public interface ResourceLoader extends AutoCloseable{ + /** + * 获取资源基本 URL + * @return URL + */ URL getBaseUrl(); + + /** + * 装载资源到ResourceStorage + * @param resourceStorage 资源存储 + * @throws Exception 装载异常 + */ void load(ResourceStorage resourceStorage) throws Exception; } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoaderFactory.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoaderFactory.java index e626f42803ab033892308def366dd0bee199dad9..60cedc88f997300f3664e38086249e4eba537b91 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoaderFactory.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/ResourceLoaderFactory.java @@ -32,7 +32,7 @@ import java.util.List; * @author starBlues * @version 3.0.0 */ -public interface ResourceLoaderFactory extends AutoCloseable{ +public interface ResourceLoaderFactory extends AutoCloseable { /** * 根据路径字符串添加资源 @@ -62,6 +62,13 @@ public interface ResourceLoaderFactory extends AutoCloseable{ */ void addResource(URL url) throws Exception; + /** + * 根据 Resource 添加 + * @param resource 资源 + * @throws Exception 添加资源异常 + */ + void addResource(Resource resource) throws Exception; + /** * 根据资源加载器添加资源 * @param resourceLoader 资源加载者 @@ -74,14 +81,14 @@ public interface ResourceLoaderFactory extends AutoCloseable{ * @param name 资源名称 * @return Resource */ - Resource findResource(String name); + Resource findFirstResource(String name); /** * 根据资源名称获取资源集合 * @param name 资源名称 * @return Resource */ - Enumeration findResources(String name); + Enumeration findAllResource(String name); /** * 根据资源名称获取第一个资源的 InputStream diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheResourceStorage.java index 9f3872f347628271890caaab792185eb79125041..a24a7c93682af71080c1eb418591302024553aa7 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheResourceStorage.java @@ -32,8 +32,6 @@ import java.util.concurrent.ConcurrentHashMap; */ public class CacheResourceStorage extends DefaultResourceStorage{ - protected final Map resourceStorage = new ConcurrentHashMap<>(); - public CacheResourceStorage(URL baseUrl) { super(baseUrl); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/DefaultResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/DefaultResourceStorage.java index 84a7733f89ff4f512e7bd856ae00b3d20bad3d89..a1f230d8aa19a8ff40645ec74ddf0a77cd6ee42e 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/DefaultResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/DefaultResourceStorage.java @@ -49,8 +49,9 @@ public class DefaultResourceStorage extends SameRootResourceStorage{ @Override public void add(String name, URL url, ResourceByteGetter byteGetter) throws Exception{ - Assert.isNotEmpty(name, "name 不能为空"); - Assert.isNotNull(url, "url 不能为空"); + if(ObjectUtils.isEmpty(name) || url == null){ + return; + } name = formatResourceName(name); if(resourceStorage.containsKey(name)){ return; @@ -61,6 +62,9 @@ public class DefaultResourceStorage extends SameRootResourceStorage{ @Override public void add(String name, URL url) throws Exception{ + if(ObjectUtils.isEmpty(name) || url == null){ + return; + } this.add(name, url, null); } @@ -74,8 +78,9 @@ public class DefaultResourceStorage extends SameRootResourceStorage{ } protected void addResource(String name, Resource resource){ - Assert.isNotEmpty(name, "name 不能为空"); - Assert.isNotNull(resource, "resource 不能为空"); + if(ObjectUtils.isEmpty(name) || resource == null){ + return; + } resourceStorage.put(name, resource); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/EmptyResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/EmptyResourceStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..72b1984ef324b15742e943277e9050b3dd29b013 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/EmptyResourceStorage.java @@ -0,0 +1,73 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.classloader.resource.storage; + +import com.gitee.starblues.loader.classloader.resource.Resource; +import com.gitee.starblues.loader.classloader.resource.ResourceByteGetter; + +import java.io.InputStream; +import java.net.URL; +import java.util.List; + +/** + * 空的资源存储 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class EmptyResourceStorage implements ResourceStorage{ + @Override + public void add(String name, URL url, ResourceByteGetter byteGetter) throws Exception { + + } + + @Override + public void add(String name, URL url) throws Exception { + + } + + @Override + public boolean exist(String name) { + return false; + } + + @Override + public Resource get(String name) { + return null; + } + + @Override + public InputStream getInputStream(String name) { + return null; + } + + @Override + public List getAll() { + return null; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void close() throws Exception { + + } +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/ShareResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/ShareResourceStorage.java index 6cd1cc9ee9fb8a56074a2352f0ac38ac78211ac3..ec61cf9e16beb43c9b0345db12e6e78e27dbf058 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/ShareResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/ShareResourceStorage.java @@ -52,6 +52,11 @@ public class ShareResourceStorage extends DefaultResourceStorage{ super.addResource(name, shareResource); } + @Override + public void close() throws Exception { + super.close(); + } + private static class ShareResource extends DefaultResource { private final static Map BYTE_STORE_MAP = new ConcurrentHashMap<>(); @@ -73,7 +78,7 @@ public class ShareResourceStorage extends DefaultResourceStorage{ if(byteStore == null){ byteStore = new ByteStore(name); byteStore.addByte(key, bytes); - BYTE_STORE_MAP.put(getName(), byteStore); + BYTE_STORE_MAP.put(name, byteStore); } else { byteStore.addByte(key, bytes); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AbstractJarFile.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AbstractJarFile.java index ae88cddfef45ce18f8ba2ae80255f97963085301..1e6f6f532cda0a028a1c8c2cf87a6efeb7920c6e 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AbstractJarFile.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AbstractJarFile.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -24,9 +25,9 @@ import java.net.URL; import java.security.Permission; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Base class for extended variants of {@link java.util.jar.JarFile}. + * + * @author Phillip Webb */ public abstract class AbstractJarFile extends java.util.jar.JarFile{ diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AsciiBytes.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AsciiBytes.java index be75721440c1efa01830a8190a2a2e52785ace13..801719b4550c97a918c09c8d547c9c751c7b0f53 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AsciiBytes.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/AsciiBytes.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -19,9 +20,11 @@ package com.gitee.starblues.loader.jar; import java.nio.charset.StandardCharsets; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Simple wrapper around a byte array that represents an ASCII. Used for performance + * reasons to save constructing Strings for ZIP data. + * + * @author Phillip Webb + * @author Andy Wilkinson */ public class AsciiBytes { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Bytes.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Bytes.java index 6b193528e1c3d656288b36ab84e3aeeb951e2290..5f3dc3c5a9f1fc0084b8c846aab36893e39c525e 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Bytes.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Bytes.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -17,9 +18,9 @@ package com.gitee.starblues.loader.jar; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Utilities for dealing with bytes from ZIP files. + * + * @author Phillip Webb */ public class Bytes { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryEndRecord.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryEndRecord.java index 3e941a34ec9cf0275908526a848517d19cb5e935..49d86d327b9b5e7abae7791a06d45d56c8b0f876 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryEndRecord.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryEndRecord.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -19,9 +20,12 @@ package com.gitee.starblues.loader.jar; import java.io.IOException; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * A ZIP File "End of central directory record" (EOCD). + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Camille Vienot + * @see Zip File Format */ public class CentralDirectoryEndRecord { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryFileHeader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryFileHeader.java index be3a47369b2f0a72230828d3a0f22ec4871e099f..a2a4d120d2196c660355599047e82c653c25db7b 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryFileHeader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryFileHeader.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -24,9 +25,12 @@ import java.time.temporal.ChronoUnit; import java.time.temporal.ValueRange; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * A ZIP File "Central directory file header record" (CDFH). + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Dmytro Nosan + * @see Zip File Format */ public class CentralDirectoryFileHeader implements FileHeader { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryParser.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryParser.java index e589c37526923106bb85520ad2e3dca7cf405013..8548c4bbb3cf4125dd8fdad0c56b7e8f509f9f17 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryParser.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryParser.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -21,9 +22,11 @@ import java.util.ArrayList; import java.util.List; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Parses the central directory from a JAR file. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @see CentralDirectoryVisitor */ public class CentralDirectoryParser { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryVisitor.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryVisitor.java index 046120ce0e118cad130b78795e557c938d82e436..2f45f46e8ee2cd516ee613d5d377bcea2a323367 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryVisitor.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/CentralDirectoryVisitor.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -17,9 +18,9 @@ package com.gitee.starblues.loader.jar; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Callback visitor triggered by {@link CentralDirectoryParser}. + * + * @author Phillip Webb */ public interface CentralDirectoryVisitor { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/FileHeader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/FileHeader.java index 7c500e4631a4cb705891944dc5bf676cc1f3c963..a360f646c6ef7d6f4a6cbd42b473076eac9f2256 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/FileHeader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/FileHeader.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -19,9 +20,11 @@ package com.gitee.starblues.loader.jar; import java.util.zip.ZipEntry; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * A file header record that has been loaded from a Jar file. + * + * @author Phillip Webb + * @see JarEntry + * @see CentralDirectoryFileHeader */ public interface FileHeader { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java index 558bb1b3c562fcedf0233fd0533e475f4ef6e53e..e8f61ed7c46876d462593e393036545e562f50e5 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -29,9 +30,12 @@ import java.util.logging.Logger; import java.util.regex.Pattern; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link URLStreamHandler} for Spring Boot loader {@link JarFile}s. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @since 1.0.0 + * @see JarFile#registerUrlProtocolHandler() */ public class Handler extends URLStreamHandler { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntry.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntry.java index b5c0a7c0501e7a9c6126847932f058a763572f65..165e79d9a9be91e6681f5e23745f64518a091501 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntry.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntry.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -25,9 +26,10 @@ import java.util.jar.Attributes; import java.util.jar.Manifest; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Extended variant of {@link java.util.jar.JarEntry} returned by {@link JarFile}s. + * + * @author Phillip Webb + * @author Andy Wilkinson */ public class JarEntry extends java.util.jar.JarEntry implements FileHeader { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryCertification.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryCertification.java index 2313ef8bf899a141404eae4792673af3c7f327cb..2ba0a165126e3264333ff4cb94cb5d2e07e193b6 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryCertification.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryCertification.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -20,9 +21,10 @@ import java.security.CodeSigner; import java.security.cert.Certificate; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link Certificate} and {@link CodeSigner} details for a {@link JarEntry} from a signed + * {@link JarFile}. + * + * @author Phillip Webb */ public class JarEntryCertification { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryFilter.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryFilter.java index defa2252f546dc788a46ca49f7ba2f489d44ff8a..e6990e7b8adf1b12236dea455e0c30ab7b50e419 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryFilter.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarEntryFilter.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -17,9 +18,9 @@ package com.gitee.starblues.loader.jar; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Interface that can be used to filter and optionally rename jar entries. + * + * @author Phillip Webb */ public interface JarEntryFilter { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFile.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFile.java index e22c64d7d44028286dd1a861c5278340fd5259aa..a02274bef273a4e2ba74b7b3b046d012bb25ed32 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFile.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFile.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -37,9 +38,18 @@ import java.util.stream.StreamSupport; import java.util.zip.ZipEntry; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Extended variant of {@link java.util.jar.JarFile} that behaves in the same way but + * offers the following additional functionality. + *
    + *
  • A nested {@link JarFile} can be {@link #getNestedJarFile(ZipEntry) obtained} based + * on any directory entry.
  • + *
  • A nested {@link JarFile} can be {@link #getNestedJarFile(ZipEntry) obtained} for + * embedded JAR files (as long as their entry is not compressed).
  • + *
+ * + * @author Phillip Webb + * @author Andy Wilkinson + * @since 1.0.0 */ public class JarFile extends AbstractJarFile implements Iterable { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileEntries.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileEntries.java index 9a45c20473d144152b49ea139e99359a239b4cb8..bb43d831e9a181a136dac45069341c0234df41e3 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileEntries.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileEntries.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -25,9 +26,18 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Provides access to entries from a {@link JarFile}. In order to reduce memory + * consumption entry details are stored using arrays. The {@code hashCodes} array stores + * the hash code of the entry name, the {@code centralDirectoryOffsets} provides the + * offset to the central directory record and {@code positions} provides the original + * order position of the entry. The arrays are stored in hashCode order so that a binary + * search can be used to find a name. + *

+ * A typical Spring Boot application will have somewhere in the region of 10,500 entries + * which should consume about 122K. + * + * @author Phillip Webb + * @author Andy Wilkinson */ public class JarFileEntries implements CentralDirectoryVisitor, Iterable { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java index 212f4c491e3f4a3ebe12b2ba865d95d5a5b46344..46d6d21204b237f97fd3a650f0ef5aa8fc93cbe1 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -34,9 +35,10 @@ import java.util.zip.ZipEntry; import com.gitee.starblues.loader.utils.ObjectUtils; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * A wrapper used to create a copy of a {@link JarFile} so that it can be safely closed + * without closing the original. + * + * @author Phillip Webb */ public class JarFileWrapper extends AbstractJarFile { @@ -132,6 +134,7 @@ public class JarFileWrapper extends AbstractJarFile { @Override public void close() throws IOException { super.close(); + // Modified Added close logic if(canClosed.get()){ for (List inputStreams : inputStreamCache.values()) { if(ObjectUtils.isEmpty(inputStreams)){ @@ -144,7 +147,8 @@ public class JarFileWrapper extends AbstractJarFile { IOUtils.closeQuietly(inputStream); } } - parent.close(); + IOUtils.closeQuietly(parent); + inputStreamCache.clear(); } } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarURLConnection.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarURLConnection.java index b2aec95dc1b7f6e43adfbe82fd47e4f1d0b3a735..5dce1fd868dab01e2455bb9a8ce6378188c2e9cb 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarURLConnection.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarURLConnection.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -24,9 +25,11 @@ import java.net.*; import java.security.Permission; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link java.net.JarURLConnection} used to support {@link JarFile#getUrl()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Rostyslav Dudka */ public class JarURLConnection extends java.net.JarURLConnection { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessData.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessData.java index 52bc2608db71b0794d1152596434ff4c0097af92..1c25ec0e76261eae80eef344fa32a3d950d57f4d 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessData.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessData.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -21,9 +22,11 @@ import java.io.IOException; import java.io.InputStream; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * Interface that provides read-only random access to some underlying data. + * Implementations must allow concurrent reads in a thread-safe manner. + * + * @author Phillip Webb + * @since 1.0.0 */ public interface RandomAccessData { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessDataFile.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessDataFile.java index 8c97592f57263990c6c104e8884837433dd9d596..7f671af88a3cc4f7ff18b50156b0a56c5dde5437 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessDataFile.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/RandomAccessDataFile.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -19,9 +20,11 @@ package com.gitee.starblues.loader.jar; import java.io.*; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link RandomAccessData} implementation backed by a {@link RandomAccessFile}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @since 1.0.0 */ public class RandomAccessDataFile implements RandomAccessData{ diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/StringSequence.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/StringSequence.java index 0cc1e8128fc8e062f53fae367b5404aeb1b2f0bd..7b2c1f73193118963299d05439764c6a708b4cef 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/StringSequence.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/StringSequence.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -19,9 +20,11 @@ package com.gitee.starblues.loader.jar; import java.util.Objects; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * A {@link CharSequence} backed by a single shared {@link String}. Unlike a regular + * {@link String}, {@link #subSequence(int, int)} operations will not copy the underlying + * character array. + * + * @author Phillip Webb */ public class StringSequence implements CharSequence { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/ZipInflaterInputStream.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/ZipInflaterInputStream.java index 05c8bf4127d6d49f2b59e56b4830bc22fabfd5ca..e4192f16de09f5cea310b6ee382c35bbe5a0c6ce 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/ZipInflaterInputStream.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/ZipInflaterInputStream.java @@ -1,11 +1,12 @@ -/** - * Copyright [2019-2022] [starBlues] +/* + * Copyright 2012-2021 the original author or authors. + * Copy from spring-boot-loader * * 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 + * https://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, @@ -23,9 +24,10 @@ import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; /** - * copy from spring-boot-loader - * @author starBlues - * @version 3.0.0 + * {@link InflaterInputStream} that supports the writing of an extra "dummy" byte (which + * is required with JDK 6) and returns accurate available() results. + * + * @author Phillip Webb */ public class ZipInflaterInputStream extends InflaterInputStream { diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractMainLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractMainLauncher.java index f68fbd37bb69a5103a49323a7067b4587275a8f6..3860e838475913b6c1ef2bbdd14716b2f12e5201 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractMainLauncher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractMainLauncher.java @@ -16,25 +16,75 @@ package com.gitee.starblues.loader.launcher; +import com.gitee.starblues.loader.DevelopmentMode; + /** * 抽象的启动引导者 * @author starBlues * @version 3.0.2 */ -public abstract class AbstractMainLauncher extends AbstractLauncher { +public abstract class AbstractMainLauncher extends AbstractLauncher { + + public static final String MAIN_CLASS_LOADER_NAME = "MainProgramLauncherClassLoader"; + + /** + * SpringPluginBootstrap 包名称 + * @since 3.0.4 + */ + private final static String SPRING_PLUGIN_BOOTSTRAP_PACKAGE_NAME = "com.gitee.starblues.bootstrap.SpringPluginBootstrap"; + + /** + * SpringPluginBootstrap 依赖坐标 + * @since 3.0.4 + */ + private final static String SPRING_PLUGIN_BOOTSTRAP_COORDINATE = "com.gitee.starblues:spring-brick-bootstrap"; + @Override - public R run(String... args) throws Exception { + public ClassLoader run(String... args) throws Exception { ClassLoader classLoader = createClassLoader(args); + if(!resolveThreadClassLoader()){ + return toLaunch(classLoader, args); + } Thread thread = Thread.currentThread(); ClassLoader oldClassLoader = thread.getContextClassLoader(); try { thread.setContextClassLoader(classLoader); - LauncherContext.setMainClassLoader(classLoader); - return launch(classLoader, args); + return toLaunch(classLoader, args); } finally { thread.setContextClassLoader(oldClassLoader); } } + protected ClassLoader toLaunch(ClassLoader classLoader, String... args) throws Exception{ + LauncherContext.setMainClassLoader(classLoader); + checkSpringPluginBootstrap(classLoader); + return launch(classLoader, args); + } + + protected boolean resolveThreadClassLoader(){ + return true; + } + + /** + * 检查 {@link this#SPRING_PLUGIN_BOOTSTRAP_COORDINATE} 依赖是否配置合适 + * @param classLoader 当前主程序classloader + * @throws RuntimeException 检查一次 + */ + private void checkSpringPluginBootstrap(ClassLoader classLoader) throws RuntimeException{ + try { + classLoader.loadClass(SPRING_PLUGIN_BOOTSTRAP_PACKAGE_NAME); + if(DevelopmentModeSetting.isolation()){ + // 主程序加载到了 + throw new RuntimeException("[" + DevelopmentMode.ISOLATION + "]模式下" + + "不能将[" + SPRING_PLUGIN_BOOTSTRAP_COORDINATE + "]依赖定义到主程序中, 只能依赖到插件中!"); + } + } catch (ClassNotFoundException e) { + if(!DevelopmentModeSetting.isolation()){ + throw new RuntimeException("[" + DevelopmentMode.COEXIST + "]模式" + + "需要将[" + SPRING_PLUGIN_BOOTSTRAP_COORDINATE + "]依赖定义到主程序中!"); + } + } + } + } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..2cac0c76c0068e1327d38e2c29ff6fc9e69b52ec --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevLauncher.java @@ -0,0 +1,50 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher; + +import com.gitee.starblues.loader.launcher.coexist.CoexistBaseLauncher; +import com.gitee.starblues.loader.launcher.isolation.IsolationBaseLauncher; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; +import lombok.AllArgsConstructor; + +/** + * 开发环境 Launcher + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +@AllArgsConstructor +public class DevLauncher implements Launcher{ + + private final SpringBootstrap springBootstrap; + + @Override + public ClassLoader run(String... args) throws Exception { + MethodRunner methodRunner = new MethodRunner(springBootstrap.getClass().getName(), + SPRING_BOOTSTRAP_RUN_METHOD, args); + AbstractMainLauncher launcher; + if(DevelopmentModeSetting.isolation()){ + launcher = new IsolationBaseLauncher(methodRunner); + } else if(DevelopmentModeSetting.coexist()) { + launcher = new CoexistBaseLauncher(methodRunner); + } else { + throw DevelopmentModeSetting.getUnknownModeException(); + } + return launcher.run(args); + } +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevelopmentModeSetting.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevelopmentModeSetting.java new file mode 100644 index 0000000000000000000000000000000000000000..2d2ee5dce216d51f93a7856cae2c72a68257e367 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/DevelopmentModeSetting.java @@ -0,0 +1,72 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher; + +import com.gitee.starblues.loader.DevelopmentMode; + +/** + * DevelopmentMode 设置者 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class DevelopmentModeSetting { + + private static String developmentMode; + + static void setDevelopmentMode(String developmentMode) { + DevelopmentModeSetting.developmentMode = checkModeKey(developmentMode); + } + + public static boolean isolation(){ + return DevelopmentMode.ISOLATION.equalsIgnoreCase(developmentMode); + } + + public static boolean coexist(){ + return DevelopmentMode.COEXIST.equalsIgnoreCase(developmentMode); + } + + public static String getDevelopmentMode(){ + return developmentMode; + } + + public static IllegalStateException getUnknownModeException(){ + return getUnknownModeException(null); + } + + public static IllegalStateException getUnknownModeException(String developmentMode){ + if(developmentMode == null || "".equals(developmentMode)){ + developmentMode = DevelopmentModeSetting.developmentMode; + } + return new IllegalStateException("不支持开发模式:" + developmentMode); + } + + private static String checkModeKey(String developmentMode){ + if(developmentMode == null || "".equals(developmentMode)){ + throw new RuntimeException("developmentMode 设置不能为空"); + } + if(DevelopmentMode.ISOLATION.equalsIgnoreCase(developmentMode)){ + return developmentMode; + } else if(DevelopmentMode.COEXIST.equalsIgnoreCase(developmentMode)){ + return developmentMode; + } else { + throw getUnknownModeException(developmentMode); + } + } + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/Launcher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/Launcher.java index cee4f124dcf06a3ed5167727a83f3eca6e94a2d3..3a996ee8456abe21262d3ca832a9e714ef13dfc3 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/Launcher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/Launcher.java @@ -23,6 +23,8 @@ package com.gitee.starblues.loader.launcher; */ public interface Launcher { + String SPRING_BOOTSTRAP_RUN_METHOD = "run"; + /** * 启动运行 * @param args 启动传入的参数 diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ProdLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ProdLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..33d34ea4eed0cc665192f1f683eb20911f87e977 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ProdLauncher.java @@ -0,0 +1,128 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher; + +import com.gitee.starblues.loader.jar.JarFile; +import com.gitee.starblues.loader.launcher.coexist.CoexistFastJarLauncher; +import com.gitee.starblues.loader.launcher.coexist.CoexistJarOuterLauncher; +import com.gitee.starblues.loader.launcher.isolation.IsolationFastJarLauncher; +import com.gitee.starblues.loader.launcher.isolation.IsolationJarOuterLauncher; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; +import com.gitee.starblues.loader.utils.ObjectUtils; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.CodeSource; +import java.security.ProtectionDomain; +import java.util.Objects; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.loader.LoaderConstant.*; + +/** + * 生产环境 Launcher + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class ProdLauncher implements Launcher{ + + static final String SPRING_BOOTSTRAP_RUN_METHOD = "run"; + + @Override + public ClassLoader run(String... args) throws Exception { + File rootJarFile = getRootJarFile(); + String startClass = null; + String mainPackageType; + String developmentMode; + try (JarFile jarFile = new JarFile(rootJarFile)){ + Manifest manifest = jarFile.getManifest(); + IllegalStateException exception = new IllegalStateException("当前启动包非法包!"); + if(manifest == null || manifest.getMainAttributes() == null){ + throw exception; + } + Attributes mainAttributes = manifest.getMainAttributes(); + startClass = mainAttributes.getValue(START_CLASS); + if (ObjectUtils.isEmpty(startClass)) { + throw exception; + } + mainPackageType = mainAttributes.getValue(MAIN_PACKAGE_TYPE); + developmentMode = mainAttributes.getValue(MAIN_DEVELOPMENT_MODE); + } + + if(ObjectUtils.isEmpty(developmentMode)){ + throw new RuntimeException("未发现 developmentMode 配置"); + } + DevelopmentModeSetting.setDevelopmentMode(developmentMode); + + MethodRunner methodRunner = new MethodRunner(startClass, SPRING_BOOTSTRAP_RUN_METHOD, args); + AbstractMainLauncher launcher; + + if(Objects.equals(mainPackageType, MAIN_PACKAGE_TYPE_JAR_OUTER)){ + launcher = getJarOuterLauncher(methodRunner, rootJarFile); + } else { + launcher = getFastJarLauncher(methodRunner, rootJarFile); + } + + return launcher.run(args); + } + + + private File getRootJarFile() throws URISyntaxException { + ProtectionDomain protectionDomain = SpringMainBootstrap.class.getProtectionDomain(); + CodeSource codeSource = protectionDomain.getCodeSource(); + URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null; + String path = (location != null) ? location.getSchemeSpecificPart() : null; + if (path == null) { + throw new IllegalStateException("Unable to determine code source archive"); + } + File root = new File(path); + if (!root.exists()) { + throw new IllegalStateException("Unable to determine code source archive from " + root); + } + return root; + } + + private AbstractMainLauncher getFastJarLauncher(MethodRunner methodRunner, File rootJarFile){ + AbstractMainLauncher launcher; + if(DevelopmentModeSetting.isolation()){ + launcher = new IsolationFastJarLauncher(methodRunner, rootJarFile); + } else if(DevelopmentModeSetting.coexist()){ + launcher = new CoexistFastJarLauncher(methodRunner, rootJarFile); + } else { + throw DevelopmentModeSetting.getUnknownModeException(); + } + return launcher; + } + + private AbstractMainLauncher getJarOuterLauncher(MethodRunner methodRunner, File rootJarFile){ + AbstractMainLauncher launcher; + if(DevelopmentModeSetting.isolation()){ + launcher = new IsolationJarOuterLauncher(methodRunner, rootJarFile); + } else if(DevelopmentModeSetting.coexist()){ + launcher = new CoexistJarOuterLauncher(methodRunner, rootJarFile); + } else { + throw DevelopmentModeSetting.getUnknownModeException(); + } + return launcher; + } + + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringBootstrap.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringBootstrap.java index 2a346604420d6c84c784fca5506f0c31e2f9ee7e..8a86ddf0d67e766f6ec4777701f045c41f966dbc 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringBootstrap.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringBootstrap.java @@ -16,6 +16,8 @@ package com.gitee.starblues.loader.launcher; +import com.gitee.starblues.loader.DevelopmentMode; + /** * 主程序实现该接口引导启动SpringBoot * @author starBlues @@ -30,4 +32,14 @@ public interface SpringBootstrap { */ void run(String[] args) throws Exception; + + /** + * 设置开发模式 + * + * @return DevelopmentMode + */ + default String developmentMode(){ + return DevelopmentMode.ISOLATION; + } + } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainBootstrap.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainBootstrap.java index 19db6ba11ad0fe97b3075d11bf52e4172c3b6a2f..bfcf712209b2702225e3a90a0841e00378edd5ab 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainBootstrap.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainBootstrap.java @@ -20,7 +20,6 @@ import com.gitee.starblues.loader.jar.JarFile; import com.gitee.starblues.loader.launcher.runner.MainMethodRunner; import com.gitee.starblues.loader.launcher.runner.MethodRunner; -import java.io.File; import java.util.Objects; import java.util.concurrent.CountDownLatch; @@ -32,13 +31,11 @@ import java.util.concurrent.CountDownLatch; public class SpringMainBootstrap { static final String MAIN_RUN_METHOD = "main"; - static final String SPRING_BOOTSTRAP_RUN_METHOD = "run"; private static final CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(1); private static SpringBootstrap springBootstrap; - public static void launch(Class bootstrapClass, String[] args) { try { SpringBootstrap springBootstrap = bootstrapClass.getConstructor().newInstance(); @@ -50,6 +47,7 @@ public class SpringMainBootstrap { public static void launch(SpringBootstrap springBootstrap, String[] args) { SpringMainBootstrap.springBootstrap = Objects.requireNonNull(springBootstrap, "springBootBootstrap 不能为空"); + DevelopmentModeSetting.setDevelopmentMode(springBootstrap.developmentMode()); MainMethodRunner mainMethodRunner = new MainMethodRunner(SpringMainBootstrap.class.getName(), MAIN_RUN_METHOD, args); JarFile.registerUrlProtocolHandler(); @@ -85,8 +83,7 @@ public class SpringMainBootstrap { private static void main(String[] args) throws Exception { Objects.requireNonNull(springBootstrap, "springBootBootstrap 不能为空"); - MethodRunner run = new MethodRunner(springBootstrap.getClass().getName(), SPRING_BOOTSTRAP_RUN_METHOD, args); - Launcher launcher = new MainProgramLauncher(run); + Launcher launcher = new DevLauncher(springBootstrap); launcher.run(args); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainProdBootstrap.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainProdBootstrap.java index 47fc054e8ec43cabcfaf691b9478404907798387..85582244b1b637d6615fede9bf10a3f62ceb7218 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainProdBootstrap.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/SpringMainProdBootstrap.java @@ -17,6 +17,8 @@ package com.gitee.starblues.loader.launcher; import com.gitee.starblues.loader.jar.JarFile; +import com.gitee.starblues.loader.launcher.isolation.IsolationJarOuterLauncher; +import com.gitee.starblues.loader.launcher.isolation.IsolationFastJarLauncher; import com.gitee.starblues.loader.launcher.runner.MethodRunner; import com.gitee.starblues.loader.utils.ObjectUtils; @@ -37,52 +39,14 @@ import static com.gitee.starblues.loader.LoaderConstant.*; */ public class SpringMainProdBootstrap { - public static void main(String[] args) throws Exception { JarFile.registerUrlProtocolHandler(); new SpringMainProdBootstrap().run(args); } private void run(String[] args) throws Exception{ - File rootJarFile = getRootJarFile(); - String startClass = null; - String mainPackageType; - try (JarFile jarFile = new JarFile(rootJarFile)){ - Manifest manifest = jarFile.getManifest(); - IllegalStateException exception = new IllegalStateException("当前启动包非法包!"); - if(manifest == null || manifest.getMainAttributes() == null){ - throw exception; - } - Attributes mainAttributes = manifest.getMainAttributes(); - startClass = mainAttributes.getValue(START_CLASS); - if (ObjectUtils.isEmpty(startClass)) { - throw exception; - } - mainPackageType = mainAttributes.getValue(MAIN_PACKAGE_TYPE); - } - MethodRunner methodRunner = new MethodRunner(startClass, SpringMainBootstrap.SPRING_BOOTSTRAP_RUN_METHOD, args); - Launcher launcher; - if(Objects.equals(mainPackageType, MAIN_PACKAGE_TYPE_JAR_OUTER)){ - launcher = new MainJarOuterProgramLauncher(methodRunner, rootJarFile); - } else { - launcher = new MainJarProgramLauncher(methodRunner, rootJarFile); - } + Launcher launcher = new ProdLauncher(); launcher.run(args); } - private File getRootJarFile() throws URISyntaxException { - ProtectionDomain protectionDomain = SpringMainBootstrap.class.getProtectionDomain(); - CodeSource codeSource = protectionDomain.getCodeSource(); - URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null; - String path = (location != null) ? location.getSchemeSpecificPart() : null; - if (path == null) { - throw new IllegalStateException("Unable to determine code source archive"); - } - File root = new File(path); - if (!root.exists()) { - throw new IllegalStateException("Unable to determine code source archive from " + root); - } - return root; - } - } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/ClasspathResource.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/ClasspathResource.java new file mode 100644 index 0000000000000000000000000000000000000000..cd296e5281fd333470ddd8ed4b0940cb64d2c4c1 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/ClasspathResource.java @@ -0,0 +1,39 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.classpath; + + +import java.net.URL; +import java.util.List; + +/** + * 获取classpath资源路径 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public interface ClasspathResource { + + /** + * 获取 classpath url 集合 + * @return List + * @throws Exception 获取异常 + */ + List getClasspath() throws Exception; + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/FastJarClasspathResource.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/FastJarClasspathResource.java new file mode 100644 index 0000000000000000000000000000000000000000..a15ad9dbd574749942c239ea5737e54caf74685a --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/FastJarClasspathResource.java @@ -0,0 +1,74 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.classpath; + +import com.gitee.starblues.loader.archive.Archive; +import com.gitee.starblues.loader.archive.ExplodedArchive; +import com.gitee.starblues.loader.archive.JarFileArchive; +import lombok.AllArgsConstructor; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static com.gitee.starblues.loader.LoaderConstant.PROD_CLASSES_PATH; +import static com.gitee.starblues.loader.LoaderConstant.PROD_LIB_PATH; + +/** + * fast jar 类型的 classpath 获取者 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +@AllArgsConstructor +public class FastJarClasspathResource implements ClasspathResource{ + + private final static Archive.EntryFilter ENTRY_FILTER = (entry)->{ + String name = entry.getName(); + return name.startsWith(PROD_CLASSES_PATH) || name.startsWith(PROD_LIB_PATH); + }; + + private final static Archive.EntryFilter INCLUDE_FILTER = (entry) -> { + if (entry.isDirectory()) { + return entry.getName().equals(PROD_CLASSES_PATH); + } + return entry.getName().startsWith(PROD_LIB_PATH); + }; + + private final File rootJarFile; + + @Override + public List getClasspath() throws Exception{ + Archive archive = getArchive(); + Iterator archiveIterator = archive.getNestedArchives(ENTRY_FILTER, INCLUDE_FILTER); + List urls = new ArrayList<>(); + while (archiveIterator.hasNext()){ + URL url = archiveIterator.next().getUrl(); + urls.add(url); + } + return urls; + } + + private Archive getArchive() throws IOException { + return (rootJarFile.isDirectory() ? new ExplodedArchive(rootJarFile) : new JarFileArchive(rootJarFile)); + } + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarOuterProgramLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/JarOutClasspathResource.java similarity index 58% rename from spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarOuterProgramLauncher.java rename to spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/JarOutClasspathResource.java index 22249d6208c5dbb2e1a410da8c55c41bd97fb3ce..69dab01b4ad405118926df5950a9841552cd1de6 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarOuterProgramLauncher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/classpath/JarOutClasspathResource.java @@ -1,29 +1,27 @@ /** * Copyright [2019-2022] [starBlues] * - * 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 + * 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. + * 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.gitee.starblues.loader.launcher; +package com.gitee.starblues.loader.launcher.classpath; import com.gitee.starblues.loader.archive.Archive; import com.gitee.starblues.loader.archive.ExplodedArchive; import com.gitee.starblues.loader.archive.JarFileArchive; -import com.gitee.starblues.loader.classloader.GenericClassLoader; -import com.gitee.starblues.loader.classloader.resource.loader.MainJarResourceLoader; -import com.gitee.starblues.loader.launcher.runner.MethodRunner; import com.gitee.starblues.loader.utils.FilesUtils; import com.gitee.starblues.loader.utils.ObjectUtils; +import lombok.AllArgsConstructor; import java.io.File; import java.io.FileFilter; @@ -34,14 +32,15 @@ import java.util.jar.Manifest; import static com.gitee.starblues.loader.LoaderConstant.*; - /** - * 主程序jar-outer 模式启动者 + * jar out 类型的 classpath 获取者 * * @author starBlues - * @version 3.0.2 + * @version 3.1.0 + * @since 3.0.4 */ -public class MainJarOuterProgramLauncher extends MainProgramLauncher{ +@AllArgsConstructor +public class JarOutClasspathResource implements ClasspathResource{ private final static Archive.EntryFilter ENTRY_FILTER = (entry)->{ @@ -58,47 +57,49 @@ public class MainJarOuterProgramLauncher extends MainProgramLauncher{ private final File rootJarFile; - public MainJarOuterProgramLauncher(MethodRunner methodRunner, File rootJarFile) { - super(methodRunner); - this.rootJarFile = Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); - } @Override - protected void addResource(GenericClassLoader classLoader) throws Exception { - super.addResource(classLoader); + public List getClasspath() throws Exception { Archive archive = getArchive(); - Iterator archiveIterator = archive.getNestedArchives(ENTRY_FILTER, INCLUDE_FILTER); - addEntryResource(archiveIterator, classLoader); - addLibResource(archive, classLoader); + Iterator archives = archive.getNestedArchives(ENTRY_FILTER, INCLUDE_FILTER); + List urls = getEntryResource(archives); + urls.addAll(getLibResource(archive)); + return urls; } private Archive getArchive() throws IOException { return (rootJarFile.isDirectory() ? new ExplodedArchive(rootJarFile) : new JarFileArchive(rootJarFile)); } - private void addEntryResource(Iterator archives, GenericClassLoader classLoader) throws Exception { + private List getEntryResource(Iterator archives) throws Exception{ + List urls = new ArrayList<>(); while (archives.hasNext()){ Archive archive = archives.next(); URL url = archive.getUrl(); String path = url.getPath(); if(path.contains(PROD_CLASSES_URL_SIGN)){ - classLoader.addResource(new MainJarResourceLoader(url)); + urls.add(url); } } + return urls; } - private void addLibResource(Archive archive, GenericClassLoader classLoader) throws Exception { + private List getLibResource(Archive archive) throws Exception{ Manifest manifest = archive.getManifest(); String libDir = manifest.getMainAttributes().getValue(MAIN_LIB_DIR); String relativePath = rootJarFile.isDirectory() ? rootJarFile.getPath() : rootJarFile.getParent(); libDir = FilesUtils.resolveRelativePath(relativePath, libDir); File libJarDir = new File(libDir); - if(libJarDir.exists()){ - List libIndexes = getLibIndexes(manifest); - addLibJarFile(libJarDir, libIndexes, classLoader); - } else { + if(!libJarDir.exists()){ throw new IllegalStateException("主程序依赖目录不存在: " + libDir); } + List libIndexes = getLibIndexes(manifest); + File[] libJarFile = getLibJarFile(libJarDir, libIndexes); + List urls = new ArrayList<>(libJarFile.length); + for (File file : libJarFile) { + urls.add(file.toPath().toUri().toURL()); + } + return urls; } private List getLibIndexes(Manifest manifest){ @@ -120,7 +121,7 @@ public class MainJarOuterProgramLauncher extends MainProgramLauncher{ return indexes; } - private void addLibJarFile(File rootFile, List libIndexes, GenericClassLoader classLoader) throws Exception { + private File[] getLibJarFile(File rootFile, List libIndexes) { Set linIndexes = new HashSet<>(libIndexes); File[] listFiles = rootFile.listFiles(new FileFilter() { @Override @@ -129,13 +130,10 @@ public class MainJarOuterProgramLauncher extends MainProgramLauncher{ } }); if(listFiles == null || listFiles.length == 0){ - return; - } - for (File listFile : listFiles) { - classLoader.addResource(listFile); + return new File[0]; } + return listFiles; } - } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistBaseLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistBaseLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..c7fffbff9be3b1be4b84d234e90ebb8d5f8108eb --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistBaseLauncher.java @@ -0,0 +1,57 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.coexist; + +import com.gitee.starblues.loader.classloader.GeneralUrlClassLoader; +import com.gitee.starblues.loader.launcher.AbstractMainLauncher; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; + + +/** + * coexist 模式 launcher + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +public class CoexistBaseLauncher extends AbstractMainLauncher { + + private final MethodRunner methodRunner; + + public CoexistBaseLauncher(MethodRunner methodRunner) { + this.methodRunner = methodRunner; + } + + @Override + protected ClassLoader createClassLoader(String... args) throws Exception { + GeneralUrlClassLoader urlClassLoader = new GeneralUrlClassLoader(MAIN_CLASS_LOADER_NAME, + this.getClass().getClassLoader()); + addResource(urlClassLoader); + return urlClassLoader; + } + + @Override + protected ClassLoader launch(ClassLoader classLoader, String... args) throws Exception { + methodRunner.run(classLoader); + return classLoader; + } + + protected void addResource(GeneralUrlClassLoader classLoader) throws Exception{ + + } + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistFastJarLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistFastJarLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..f882a1792e8cf0c0a8eb3f9e31bacc682f19a7aa --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistFastJarLauncher.java @@ -0,0 +1,59 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.coexist; + +import com.gitee.starblues.loader.classloader.GeneralUrlClassLoader; +import com.gitee.starblues.loader.launcher.classpath.ClasspathResource; +import com.gitee.starblues.loader.launcher.classpath.FastJarClasspathResource; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.Objects; + +/** + * 主程序jar in jar 模式启动者 + * @author starBlues + * @version 3.0.2 + */ +public class CoexistFastJarLauncher extends CoexistBaseLauncher { + + private final ClasspathResource classpathResource; + + public CoexistFastJarLauncher(MethodRunner methodRunner, File rootJarFile) { + super(methodRunner); + Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); + this.classpathResource = new FastJarClasspathResource(rootJarFile); + } + + @Override + protected boolean resolveThreadClassLoader() { + return true; + } + + @Override + protected void addResource(GeneralUrlClassLoader classLoader) throws Exception { + super.addResource(classLoader); + List classpath = classpathResource.getClasspath(); + for (URL url : classpath) { + classLoader.addResource(url); + } + } + + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistJarOuterLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistJarOuterLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..f3ee5ac9fce95f5363aa9d0e9576313fb59ed2f5 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/coexist/CoexistJarOuterLauncher.java @@ -0,0 +1,61 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.coexist; + +import com.gitee.starblues.loader.classloader.GeneralUrlClassLoader; +import com.gitee.starblues.loader.launcher.classpath.ClasspathResource; +import com.gitee.starblues.loader.launcher.classpath.JarOutClasspathResource; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.Objects; + + +/** + * 主程序jar-outer 模式启动者 + * + * @author starBlues + * @version 3.0.2 + */ +public class CoexistJarOuterLauncher extends CoexistBaseLauncher { + + private final ClasspathResource classpathResource; + + public CoexistJarOuterLauncher(MethodRunner methodRunner, File rootJarFile) { + super(methodRunner); + Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); + this.classpathResource = new JarOutClasspathResource(rootJarFile); + } + + @Override + protected boolean resolveThreadClassLoader() { + return true; + } + + @Override + protected void addResource(GeneralUrlClassLoader classLoader) throws Exception { + super.addResource(classLoader); + List classpath = classpathResource.getClasspath(); + for (URL url : classpath) { + classLoader.addResource(url); + } + } + + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainProgramLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationBaseLauncher.java similarity index 85% rename from spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainProgramLauncher.java rename to spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationBaseLauncher.java index 00ce88a3ddc352bd49c6945c7e86852240ea0399..9cb11d53539eb428673bbe7e082a3b5c9447e72f 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainProgramLauncher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationBaseLauncher.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package com.gitee.starblues.loader.launcher; +package com.gitee.starblues.loader.launcher.isolation; import com.gitee.starblues.loader.classloader.GenericClassLoader; import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; +import com.gitee.starblues.loader.launcher.AbstractMainLauncher; import com.gitee.starblues.loader.launcher.runner.MethodRunner; import com.gitee.starblues.loader.utils.ObjectUtils; @@ -31,20 +32,23 @@ import java.net.URLClassLoader; * @author starBlues * @version 3.0.0 */ -public class MainProgramLauncher extends AbstractMainLauncher{ - - public static final String MAIN_CLASS_LOADER_NAME = "MainProgramLauncherClassLoader"; +public class IsolationBaseLauncher extends AbstractMainLauncher { private final MethodRunner methodRunner; - public MainProgramLauncher(MethodRunner methodRunner) { + public IsolationBaseLauncher(MethodRunner methodRunner) { this.methodRunner = methodRunner; } + @Override + protected boolean resolveThreadClassLoader() { + return false; + } + @Override protected ClassLoader createClassLoader(String... args) throws Exception { GenericClassLoader classLoader = new GenericClassLoader(MAIN_CLASS_LOADER_NAME, getParentClassLoader(), - getResourceLoaderFactory()); + getResourceLoaderFactory(args)); addResource(classLoader); return classLoader; } @@ -60,7 +64,7 @@ public class MainProgramLauncher extends AbstractMainLauncher{ } protected ClassLoader getParentClassLoader(){ - return MainProgramLauncher.class.getClassLoader(); + return IsolationBaseLauncher.class.getClassLoader(); } protected void addResource(GenericClassLoader classLoader) throws Exception{ diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarProgramLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationFastJarLauncher.java similarity index 50% rename from spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarProgramLauncher.java rename to spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationFastJarLauncher.java index c423b92636ca0caf45c6073f6338385188a62e20..8b4928f96c4296be7508940f3147117ce47efbcf 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/MainJarProgramLauncher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationFastJarLauncher.java @@ -14,20 +14,18 @@ * limitations under the License. */ -package com.gitee.starblues.loader.launcher; +package com.gitee.starblues.loader.launcher.isolation; -import com.gitee.starblues.loader.archive.Archive; -import com.gitee.starblues.loader.archive.ExplodedArchive; -import com.gitee.starblues.loader.archive.JarFileArchive; import com.gitee.starblues.loader.classloader.GenericClassLoader; import com.gitee.starblues.loader.classloader.resource.loader.JarResourceLoader; import com.gitee.starblues.loader.classloader.resource.loader.MainJarResourceLoader; +import com.gitee.starblues.loader.launcher.classpath.ClasspathResource; +import com.gitee.starblues.loader.launcher.classpath.FastJarClasspathResource; import com.gitee.starblues.loader.launcher.runner.MethodRunner; import java.io.File; -import java.io.IOException; import java.net.URL; -import java.util.Iterator; +import java.util.List; import java.util.Objects; import static com.gitee.starblues.loader.LoaderConstant.*; @@ -37,43 +35,26 @@ import static com.gitee.starblues.loader.LoaderConstant.*; * @author starBlues * @version 3.0.2 */ -public class MainJarProgramLauncher extends MainProgramLauncher{ +public class IsolationFastJarLauncher extends IsolationBaseLauncher { - private final static Archive.EntryFilter ENTRY_FILTER = (entry)->{ - String name = entry.getName(); - return name.startsWith(PROD_CLASSES_PATH) || name.startsWith(PROD_LIB_PATH); - }; + private final ClasspathResource classpathResource; - private final static Archive.EntryFilter INCLUDE_FILTER = (entry) -> { - if (entry.isDirectory()) { - return entry.getName().equals(PROD_CLASSES_PATH); - } - return entry.getName().startsWith(PROD_LIB_PATH); - }; - - private final File rootJarFile; - - public MainJarProgramLauncher(MethodRunner methodRunner, File rootJarFile) { + public IsolationFastJarLauncher(MethodRunner methodRunner, File rootJarFile) { super(methodRunner); - this.rootJarFile = Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); + Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); + this.classpathResource = new FastJarClasspathResource(rootJarFile); } @Override - protected void addResource(GenericClassLoader classLoader) throws Exception { - super.addResource(classLoader); - Archive archive = getArchive(); - Iterator archiveIterator = archive.getNestedArchives(ENTRY_FILTER, INCLUDE_FILTER); - addLibResource(archiveIterator, classLoader); + protected boolean resolveThreadClassLoader() { + return true; } - private Archive getArchive() throws IOException { - return (rootJarFile.isDirectory() ? new ExplodedArchive(rootJarFile) : new JarFileArchive(rootJarFile)); - } - - private void addLibResource(Iterator archives, GenericClassLoader classLoader) throws Exception { - while (archives.hasNext()){ - Archive archive = archives.next(); - URL url = archive.getUrl(); + @Override + protected void addResource(GenericClassLoader classLoader) throws Exception { + super.addResource(classLoader); + List classpath = classpathResource.getClasspath(); + for (URL url : classpath) { String path = url.getPath(); if(path.contains(PROD_CLASSES_URL_SIGN)){ classLoader.addResource(new MainJarResourceLoader(url)); @@ -83,4 +64,5 @@ public class MainJarProgramLauncher extends MainProgramLauncher{ } } + } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationJarOuterLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationJarOuterLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..f06013f3f0be07c94be106a312f6b93af43434a2 --- /dev/null +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/IsolationJarOuterLauncher.java @@ -0,0 +1,60 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.loader.launcher.isolation; + +import com.gitee.starblues.loader.classloader.GenericClassLoader; +import com.gitee.starblues.loader.launcher.classpath.ClasspathResource; +import com.gitee.starblues.loader.launcher.classpath.JarOutClasspathResource; +import com.gitee.starblues.loader.launcher.runner.MethodRunner; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.Objects; + + +/** + * 主程序jar-outer 模式启动者 + * + * @author starBlues + * @version 3.0.2 + */ +public class IsolationJarOuterLauncher extends IsolationBaseLauncher { + + private final ClasspathResource classpathResource; + + public IsolationJarOuterLauncher(MethodRunner methodRunner, File rootJarFile) { + super(methodRunner); + Objects.requireNonNull(rootJarFile, "参数 rootJarFile 不能为空"); + this.classpathResource = new JarOutClasspathResource(rootJarFile); + } + + @Override + protected boolean resolveThreadClassLoader() { + return true; + } + + @Override + protected void addResource(GenericClassLoader classLoader) throws Exception { + super.addResource(classLoader); + List classpath = classpathResource.getClasspath(); + for (URL url : classpath) { + classLoader.addResource(url); + } + } + +} diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ResourceLoaderFactoryGetter.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/ResourceLoaderFactoryGetter.java similarity index 86% rename from spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ResourceLoaderFactoryGetter.java rename to spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/ResourceLoaderFactoryGetter.java index 61dbbd94883a0fdd3b179c87493558acf95fa05b..719f2a5a3f23ff7729a27026a6242a4b911bb8b7 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/ResourceLoaderFactoryGetter.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/isolation/ResourceLoaderFactoryGetter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.gitee.starblues.loader.launcher; +package com.gitee.starblues.loader.launcher.isolation; import com.gitee.starblues.loader.classloader.resource.loader.DefaultResourceLoaderFactory; import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; @@ -46,11 +46,6 @@ public class ResourceLoaderFactoryGetter { private static final String RESOURCE_MODE_CACHE_SHARE = "cache-share"; - /** - * 资源模式--不缓存模式 - */ - private static final String RESOURCE_MODE_NO_CACHE = "no-cache"; - private static volatile String resourceMode; @@ -80,12 +75,12 @@ public class ResourceLoaderFactoryGetter { public static SameRootResourceStorage getResourceStorage(String key, URL baseUrl){ SameRootResourceStorage resourceStorage = null; - if(Objects.equals(resourceMode, RESOURCE_MODE_NO_CACHE)){ - resourceStorage = new DefaultResourceStorage(baseUrl); - } else if(Objects.equals(resourceMode, RESOURCE_MODE_CACHE_SHARE)){ - resourceStorage = new ShareResourceStorage(key, baseUrl); - } else { + if(Objects.equals(resourceMode, RESOURCE_MODE_CACHE_ISOLATION)){ + // 资源可缓存, 且隔离 resourceStorage = new CacheResourceStorage(baseUrl); + } else { + // 资源可缓存, 共享式 + resourceStorage = new ShareResourceStorage(key, baseUrl); } return resourceStorage; } diff --git a/spring-brick-maven-packager/pom.xml b/spring-brick-maven-packager/pom.xml index cb70eb68bc05abbc3b5e69b7dd200b962edfc58e..cacdf5d7e5617b97b06a8b101a91bbe95828ca32 100644 --- a/spring-brick-maven-packager/pom.xml +++ b/spring-brick-maven-packager/pom.xml @@ -7,7 +7,7 @@ spring-brick-parent com.gitee.starblues - 3.0.3 + 3.1.0 spring-brick-maven-packager diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java index b66fe5d1dedabcf8db9547b459b9ef5279c06055..ce11f06dd41fca3c294383f42b69fffe34a5c1b3 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java @@ -41,6 +41,12 @@ public class Constant { public static final String PLUGIN_METE_COMMENTS = "plugin meta configuration"; + /** + * 开发模式方法名称 + */ + public static final String DEVELOPMENT_MODE_METHOD_NAME = "developmentMode"; + + public static boolean isPom(String packageType){ return PACKAGING_POM.equalsIgnoreCase(packageType); } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java index e866c3d373098fadf8431acb04ee3ee4b47f1139..3b9eeb972f16bb9f066b0261c6643a4187fc0f21 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java @@ -22,11 +22,11 @@ import com.gitee.starblues.plugin.pack.RepackageMojo; import com.gitee.starblues.plugin.pack.Repackager; import com.gitee.starblues.plugin.pack.utils.CommonUtils; import com.gitee.starblues.plugin.pack.utils.PackageJar; -import com.gitee.starblues.utils.ObjectUtils; import org.apache.commons.io.IOUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; import java.io.File; import java.util.Set; @@ -83,6 +83,12 @@ public class JarNestPackager implements Repackager { attributes.putValue(START_CLASS, mainConfig.getMainClass()); attributes.putValue(MAIN_CLASS, MAIN_CLASS_VALUE); attributes.putValue(MAIN_PACKAGE_TYPE, PackageType.MAIN_PACKAGE_TYPE_JAR); + attributes.putValue(DEVELOPMENT_MODE, mainConfig.getDevelopmentMode()); + + // 增加jar包title和version属性 + MavenProject mavenProject = this.repackageMojo.getProject(); + attributes.putValue(IMPLEMENTATION_TITLE, mavenProject.getArtifactId()); + attributes.putValue(IMPLEMENTATION_VERSION, mavenProject.getVersion()); return manifest; } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java index de5a493c8a6b258a0bb1acb3755afffc283f5d84..f4db7cad9e194472b89e3f63145acb79ed931879 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java @@ -25,13 +25,13 @@ import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; import java.io.File; import java.util.HashSet; import java.util.Set; import java.util.jar.Attributes; import java.util.jar.Manifest; -import java.util.stream.Stream; import static com.gitee.starblues.common.ManifestKey.*; @@ -86,7 +86,12 @@ public class JarOuterPackager extends JarNestPackager { attributes.putValue(MAIN_CLASS, MAIN_CLASS_VALUE); attributes.putValue(MAIN_PACKAGE_TYPE, PackageType.MAIN_PACKAGE_TYPE_JAR_OUTER); attributes.putValue(MAIN_LIB_DIR, getLibPath()); - attributes.putValue(MAIN_LIB_INDEXES, getLibIndexes()); + attributes.putValue(DEVELOPMENT_MODE, mainConfig.getDevelopmentMode()); + + // 增加jar包title和version属性 + MavenProject mavenProject = this.repackageMojo.getProject(); + attributes.putValue(IMPLEMENTATION_TITLE, mavenProject.getArtifactId()); + attributes.putValue(IMPLEMENTATION_VERSION, mavenProject.getVersion()); return manifest; } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java index f8ee0ee39b6335e6ab73e28761ff38d66e8dab15..1640483757c6b36b8abcaac5e15ddc0c1cc4b6d7 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java @@ -16,11 +16,8 @@ package com.gitee.starblues.plugin.pack.main; - -import com.gitee.starblues.common.PackageStructure; import lombok.Data; import org.apache.maven.plugins.annotations.Parameter; -import com.gitee.starblues.plugin.pack.Constant; /** * 主程序打包配置 @@ -59,6 +56,12 @@ public class MainConfig { */ private String outputDirectory; - + /** + * 开发模式: + * isolation: 隔离模式[默认] + * coexist: 共享模式 + * simple: 简单模式 + */ + private String developmentMode; } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java index a32d278c951951c0198ccb293ed2ecffdf78f745..e0d73f293a4f076108426a37b50ae729ea5e7e98 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java @@ -17,14 +17,24 @@ package com.gitee.starblues.plugin.pack.main; import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.plugin.pack.Constant; import com.gitee.starblues.plugin.pack.RepackageMojo; import com.gitee.starblues.plugin.pack.Repackager; import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.ReflectionUtils; import lombok.Getter; +import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Set; + /** * 主程序打包 * @author starBlues @@ -44,6 +54,7 @@ public class MainRepackager implements Repackager { @Override public void repackage() throws MojoExecutionException, MojoFailureException { checkConfig(); + setDevelopmentMode(); String packageType = mainConfig.getPackageType(); if(PackageType.MAIN_PACKAGE_TYPE_JAR.equalsIgnoreCase(packageType)){ new JarNestPackager(this).repackage(); @@ -76,5 +87,45 @@ public class MainRepackager implements Repackager { } } + private void setDevelopmentMode() throws MojoFailureException{ + String developmentMode = mainConfig.getDevelopmentMode(); + if(!ObjectUtils.isEmpty(developmentMode)){ + return; + } + try { + File file = new File(repackageMojo.getProject().getBuild().getOutputDirectory()); + Set artifacts = repackageMojo.getProject().getArtifacts(); + + URL[] urls = new URL[artifacts.size() + 1]; + int i = 0; + for (Artifact artifact : artifacts) { + urls[i] = artifact.getFile().toURI().toURL(); + i++; + } + urls[i] = file.toURI().toURL(); + URLClassLoader urlClassLoader = new URLClassLoader(urls, null); + + String mainClass = repackageMojo.getMainConfig().getMainClass(); + if(ObjectUtils.isEmpty(mainClass)){ + throw new Exception("mainConfig.mainClass config can't be empty"); + } + Class aClass = urlClassLoader.loadClass(mainClass); + Method method = ReflectionUtils.findMethod(aClass, Constant.DEVELOPMENT_MODE_METHOD_NAME); + String methodKey = aClass.getName() + "#" + Constant.DEVELOPMENT_MODE_METHOD_NAME + "()"; + if(method == null){ + throw new Exception("Not found method : " + methodKey); + } + method.setAccessible(true); + Object o = aClass.getConstructor().newInstance(); + Object result = method.invoke(o); + if(ObjectUtils.isEmpty(result)){ + throw new Exception(methodKey + " return value can't be empty"); + } + getMainConfig().setDevelopmentMode(String.valueOf(result)); + } catch (Exception e) { + throw new MojoFailureException("Set developmentMode failure:" + e.getMessage()); + } + } + } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java index 303fd54ad009a6e8211ca4128b123607fcf894d9..55ca1548b9a9ccdfe3620300e10dc76bc479cf70 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java @@ -174,8 +174,10 @@ public class ZipProdRepackager extends DevRepackager { if(filterArtifact(artifact)){ continue; } - String dependencyIndexName = packageZip.writeDependency(artifact.getFile(), libDirEntryName); - dependencyIndexNames.add(dependencyIndexName); + File artifactFile = artifact.getFile(); + packageZip.writeDependency(artifactFile, libDirEntryName); + // fix 解决依赖前缀携带, lib 配置的前缀 + dependencyIndexNames.add(artifactFile.getName()); } return dependencyIndexNames; } diff --git a/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml b/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml index ddfb1ce44fb119f21f5ada61509aea1ebc8ee3ae..0e203ae57eaeed9b4893fdbd89c11fa31e7563db 100644 --- a/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml +++ b/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml @@ -4,7 +4,7 @@ Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.3 + 3.1.0 spring-brick-packager false true diff --git a/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml b/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml index ddfb1ce44fb119f21f5ada61509aea1ebc8ee3ae..0e203ae57eaeed9b4893fdbd89c11fa31e7563db 100644 --- a/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml +++ b/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml @@ -4,7 +4,7 @@ Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.3 + 3.1.0 spring-brick-packager false true diff --git a/spring-brick/pom.xml b/spring-brick/pom.xml index c92fc860fbfdbaf16ba242fc7d719a342c6b1dfb..9118a928c57c778e8fee5426008634a78e6362f5 100644 --- a/spring-brick/pom.xml +++ b/spring-brick/pom.xml @@ -7,7 +7,7 @@ spring-brick-parent com.gitee.starblues - 3.0.3 + 3.1.0 spring-brick diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginInsideInfo.java b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginInsideInfo.java index 1f562254ce1aa67294c213104c5fff0755653256..1fdaf5b512febb835bffe435bf39454d51306874 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginInsideInfo.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginInsideInfo.java @@ -18,8 +18,12 @@ package com.gitee.starblues.core; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.utils.Assert; +import lombok.Setter; +import java.util.Collections; import java.util.Date; +import java.util.Map; +import java.util.function.Supplier; /** * 默认的内部PluginWrapperInside实现 @@ -36,6 +40,8 @@ public class DefaultPluginInsideInfo implements PluginInsideInfo { private Date startTime; private Date stopTime; + private Supplier> extensionInfoSupplier = Collections::emptyMap; + public DefaultPluginInsideInfo(InsidePluginDescriptor pluginDescriptor) { this.pluginId = pluginDescriptor.getPluginId(); this.pluginDescriptor = pluginDescriptor; @@ -52,6 +58,16 @@ public class DefaultPluginInsideInfo implements PluginInsideInfo { isFollowInitial = true; } + @Override + public void setExtensionInfoSupplier(Supplier> supplier) { + this.extensionInfoSupplier = supplier; + } + + @Override + public Supplier> getExtensionInfoSupplier() { + return extensionInfoSupplier; + } + @Override public String getPluginId() { return pluginId; @@ -92,6 +108,11 @@ public class DefaultPluginInsideInfo implements PluginInsideInfo { return isFollowInitial; } + @Override + public Map getExtensionInfo() { + return extensionInfoSupplier.get(); + } + private void resolveTime(PluginState pluginState){ if(pluginState == PluginState.STARTED || pluginState == PluginState.STARTED_FAILURE){ startTime = new Date(); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java index ac678a21772abae3f55ade7d69391468b536b782..d7ab7bbe3e8630ab51ca3fd000ec7c187def5276 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java @@ -49,7 +49,8 @@ import java.util.stream.Collectors; /** * 抽象的插件管理者 * @author starBlues - * @version 3.0.3 + * @since 3.0.0 + * @version 3.1.0 */ public class DefaultPluginManager implements PluginManager{ @@ -179,6 +180,7 @@ public class DefaultPluginManager implements PluginManager{ if(pluginInsideInfo == null){ throw new PluginException("非法插件包: " + pluginPath); } + pluginInsideInfo.setPluginState(PluginState.PARSED); return pluginInsideInfo.toPluginInfo(); } @@ -251,7 +253,8 @@ public class DefaultPluginManager implements PluginManager{ } PluginException pluginException = PluginException.getPluginException(e, ()-> { unLoad(loadPluginInfo.getPluginId()); - throw new PluginException("插件包[ " + pluginPath + " ]安装: " + e.getMessage(), e); + // fix https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I5GJO9 + return new PluginException("插件包[ " + pluginPath + " ]安装: " + e.getMessage(), e); }); pluginListenerFactory.startFailure(pluginInfo, pluginException); throw pluginException; @@ -260,28 +263,10 @@ public class DefaultPluginManager implements PluginManager{ @Override public synchronized void uninstall(String pluginId) throws PluginException { - Assert.isNotNull(pluginId, "参数pluginId不能为空"); - PluginInsideInfo wrapperInside = getPlugin(pluginId); - if(wrapperInside == null){ - throw new PluginException("没有发现插件: " + pluginId); - } - PluginInfo pluginInfo = wrapperInside.toPluginInfo(); - if(wrapperInside.getPluginState() == PluginState.STARTED){ - try { - stop(wrapperInside); - pluginListenerFactory.stopSuccess(pluginInfo); - } catch (Throwable e) { - PluginException pluginException = PluginException.getPluginException(e, - ()-> new PluginException("停止", pluginId, e)); - pluginListenerFactory.stopFailure(pluginInfo, pluginException); - throw pluginException; - } - } - startedPlugins.remove(pluginId); - unLoad(pluginId); - LogUtils.info(log, wrapperInside.getPluginDescriptor(), "卸载成功"); + uninstall(pluginId, PluginCloseType.UNINSTALL); } + @Override public synchronized PluginInfo upgrade(Path pluginPath, boolean unpackPlugin) throws PluginException { Assert.isNotNull(pluginPath, "参数pluginPath不能为空"); @@ -304,7 +289,7 @@ public class DefaultPluginManager implements PluginManager{ checkVersion(oldPlugin.getPluginDescriptor(), upgradePluginDescriptor); if(oldPlugin.getPluginState() == PluginState.STARTED){ // 如果插件被启动, 则卸载旧的插件 - uninstall(pluginId); + uninstall(pluginId, PluginCloseType.UPGRADE_UNINSTALL); } else if(oldPlugin.getPluginState() == PluginState.LOADED){ // 如果插件被load unLoad(pluginId); @@ -348,13 +333,13 @@ public class DefaultPluginManager implements PluginManager{ if(ObjectUtils.isEmpty(pluginId)){ return null; } - PluginInsideInfo pluginInsideInfo = startedPlugins.get(pluginId); + PluginInsideInfo pluginInsideInfo = getPlugin(pluginId); if(pluginInsideInfo == null){ throw new PluginException("没有发现插件: " + pluginId); } PluginInfo pluginInfo = pluginInsideInfo.toPluginInfo(); try { - stop(pluginInsideInfo); + stop(pluginInsideInfo, PluginCloseType.STOP); log.info("停止插件[{}]成功", MsgUtils.getPluginUnique(pluginInsideInfo.getPluginDescriptor())); pluginListenerFactory.stopSuccess(pluginInfo); return pluginInfo; @@ -395,6 +380,35 @@ public class DefaultPluginManager implements PluginManager{ return pluginDescriptors; } + /** + * 卸载插件 + * @param pluginId 插件id + * @param closeType 关闭类型 + * @throws PluginException 卸载异常 + */ + protected void uninstall(String pluginId, PluginCloseType closeType) throws PluginException{ + Assert.isNotNull(pluginId, "参数pluginId不能为空"); + PluginInsideInfo wrapperInside = getPlugin(pluginId); + if(wrapperInside == null){ + throw new PluginException("没有发现插件: " + pluginId); + } + PluginInfo pluginInfo = wrapperInside.toPluginInfo(); + if(wrapperInside.getPluginState() == PluginState.STARTED){ + try { + stop(wrapperInside, closeType); + pluginListenerFactory.stopSuccess(pluginInfo); + } catch (Throwable e) { + PluginException pluginException = PluginException.getPluginException(e, + ()-> new PluginException("停止", pluginId, e)); + pluginListenerFactory.stopFailure(pluginInfo, pluginException); + throw pluginException; + } + } + startedPlugins.remove(pluginId); + unLoad(pluginId); + LogUtils.info(log, wrapperInside.getPluginDescriptor(), "卸载成功"); + } + protected PluginInsideInfo loadPlugin(Path pluginPath, boolean resolvePath) { if(resolvePath){ Path sourcePluginPath = pluginPath; @@ -536,14 +550,14 @@ public class DefaultPluginManager implements PluginManager{ /** * 统一停止插件操作 * @param pluginInsideInfo PluginInsideInfo + * @param closeType 停止类型 * @throws Exception 启动异常 */ - protected void stop(PluginInsideInfo pluginInsideInfo) throws Exception{ + protected void stop(PluginInsideInfo pluginInsideInfo, PluginCloseType closeType) throws Exception{ launcherChecker.checkCanStop(pluginInsideInfo); pluginInsideInfo.setPluginState(PluginState.STOPPED); stopFinish(pluginInsideInfo); } - /** * 停止完成操作 * @param pluginInsideInfo pluginInsideInfo diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginCloseType.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginCloseType.java new file mode 100644 index 0000000000000000000000000000000000000000..0aef5e47d9a0c2af98fd89fe02cb2266223c2a25 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginCloseType.java @@ -0,0 +1,27 @@ +package com.gitee.starblues.core; + +/** + * 插件关闭类型 + * + * @author starBlues + * @since 3.1.0 + * @version 3.1.0 + */ +public enum PluginCloseType { + + /** + * 直接操作停止 + */ + STOP, + + /** + * 卸载时停止 + */ + UNINSTALL, + + /** + * 升级时停止 + */ + UPGRADE_UNINSTALL + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginExtensionInfo.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginExtensionInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..a741d01af8960708b63143e67c50ac4f0032ab11 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginExtensionInfo.java @@ -0,0 +1,21 @@ +package com.gitee.starblues.core; + +import java.util.Map; + +/** + * 自主实现插件的扩展信息 + * + * @author starBlues + * @version 3.1.0 + * @since 3.1.0 + */ +public interface PluginExtensionInfo { + + /** + * 实现返回扩展信息 + * @return 扩展信息Map + */ + Map extensionInfo(); + + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfo.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfo.java index 851d1f810f2dc0be811bdeba3b458e9fcd74887a..9cf4d18bec3e8e7419876517be5399aea62dd0ed 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfo.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfo.java @@ -19,6 +19,7 @@ package com.gitee.starblues.core; import com.gitee.starblues.core.descriptor.PluginDescriptor; import java.util.Date; +import java.util.Map; /** * 插件信息 @@ -63,11 +64,16 @@ public interface PluginInfo { */ Date getStopTime(); - /** * 是否跟随系统启动而加载的插件 * @return true: 是, false: 否 */ boolean isFollowSystem(); + /** + * 获取插件自主扩展信息 + * @return 扩展信息Map + */ + Map getExtensionInfo(); + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfoFace.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfoFace.java index 0822f8418c5d4d683c4d4de79c41a2aefafc6ebc..d0d53d793cf31bc30c16c87b1dee9a04d0f92e03 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfoFace.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInfoFace.java @@ -20,6 +20,8 @@ import com.gitee.starblues.core.descriptor.PluginDescriptor; import com.gitee.starblues.utils.Assert; import java.util.Date; +import java.util.Map; +import java.util.function.Supplier; /** * 外部 PluginWrapperFace @@ -31,6 +33,7 @@ public class PluginInfoFace implements PluginInfo { private final PluginDescriptor pluginDescriptor; private final PluginState pluginState; private final boolean followSystem; + private final Supplier> extensionInfoSupplier; private final Date startTime; private final Date stopTime; @@ -40,6 +43,7 @@ public class PluginInfoFace implements PluginInfo { this.pluginDescriptor = pluginInsideInfo.getPluginDescriptor().toPluginDescriptor(); this.pluginState = pluginInsideInfo.getPluginState(); this.followSystem = pluginInsideInfo.isFollowSystem(); + this.extensionInfoSupplier = pluginInsideInfo.getExtensionInfoSupplier(); this.startTime = pluginInsideInfo.getStartTime(); this.stopTime = pluginInsideInfo.getStopTime(); } @@ -78,4 +82,9 @@ public class PluginInfoFace implements PluginInfo { public boolean isFollowSystem() { return followSystem; } + + @Override + public Map getExtensionInfo() { + return extensionInfoSupplier.get(); + } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInsideInfo.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInsideInfo.java index 1c2a39c6cc6fbc3f8a3942a8e46317e119164dc4..0d7d7d6c7be6b3f1b6c934c73f9eb6a10e26fd79 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginInsideInfo.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginInsideInfo.java @@ -18,9 +18,14 @@ package com.gitee.starblues.core; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import java.util.Map; +import java.util.function.Supplier; + /** * 内部的 PluginInfo - * @version 3.0.0 + * + * @since 3.0.0 + * @version 3.1.0 * @author starBlues */ public interface PluginInsideInfo extends PluginInfo { @@ -36,6 +41,18 @@ public interface PluginInsideInfo extends PluginInfo { */ void setFollowSystem(); + /** + * 设置插件扩展信息 + * @param supplier 插件扩展信息自主提供者 + */ + void setExtensionInfoSupplier(Supplier> supplier); + + /** + * 获取插件信息提供者 + * @return 插件扩展信息自主提供者 + */ + Supplier> getExtensionInfoSupplier(); + /** * 得到插件描述 * @return PluginDescriptor diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java index a7b4f05400e5712246701c4293ffd87bde2f59d9..bb153015db28139855f0eda69ebc2072efe6d30b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java @@ -23,12 +23,15 @@ import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.core.exception.PluginProhibitStopException; import com.gitee.starblues.core.launcher.plugin.DefaultPluginInteractive; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; -import com.gitee.starblues.core.launcher.plugin.PluginLauncher; +import com.gitee.starblues.core.launcher.plugin.PluginCoexistLauncher; +import com.gitee.starblues.core.launcher.plugin.PluginIsolationLauncher; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolvedFactory; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.integration.listener.DefaultPluginListenerFactory; import com.gitee.starblues.integration.listener.PluginListenerFactory; +import com.gitee.starblues.loader.launcher.AbstractLauncher; +import com.gitee.starblues.loader.launcher.DevelopmentModeSetting; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.MainApplicationContextProxy; import com.gitee.starblues.spring.SpringPluginHook; @@ -45,7 +48,7 @@ import java.util.concurrent.ConcurrentHashMap; * 可引导启动的插件管理者 * @author starBlues * @since 3.0.0 - * @version 3.0.3 + * @version 3.1.0 */ public class PluginLauncherManager extends DefaultPluginManager{ @@ -94,9 +97,16 @@ public class PluginLauncherManager extends DefaultPluginManager{ launcherChecker.checkCanStart(pluginInsideInfo); try { InsidePluginDescriptor pluginDescriptor = pluginInsideInfo.getPluginDescriptor(); - PluginInteractive pluginInteractive = new DefaultPluginInteractive(pluginDescriptor, + PluginInteractive pluginInteractive = new DefaultPluginInteractive(pluginInsideInfo, mainApplicationContext, configuration, invokeSupperCache); - PluginLauncher pluginLauncher = new PluginLauncher(pluginInteractive, pluginLaunchInvolved); + AbstractLauncher pluginLauncher; + if(DevelopmentModeSetting.isolation()){ + pluginLauncher = new PluginIsolationLauncher(pluginInteractive, pluginLaunchInvolved); + } else if(DevelopmentModeSetting.coexist()){ + pluginLauncher = new PluginCoexistLauncher(pluginInteractive, pluginLaunchInvolved); + } else { + throw DevelopmentModeSetting.getUnknownModeException(); + } SpringPluginHook springPluginHook = pluginLauncher.run(); RegistryPluginInfo registryPluginInfo = new RegistryPluginInfo(pluginDescriptor, springPluginHook); registryInfo.put(pluginDescriptor.getPluginId(), registryPluginInfo); @@ -109,9 +119,9 @@ public class PluginLauncherManager extends DefaultPluginManager{ } } - @Override - protected void stop(PluginInsideInfo pluginInsideInfo) throws Exception { + protected void stop(PluginInsideInfo pluginInsideInfo, PluginCloseType closeType) throws Exception { + launcherChecker.checkCanStop(pluginInsideInfo); String pluginId = pluginInsideInfo.getPluginId(); RegistryPluginInfo registryPluginInfo = registryInfo.get(pluginId); if(registryPluginInfo == null){ @@ -120,10 +130,10 @@ public class PluginLauncherManager extends DefaultPluginManager{ try { SpringPluginHook springPluginHook = registryPluginInfo.getSpringPluginHook(); springPluginHook.stopVerify(); - springPluginHook.close(); + springPluginHook.close(closeType); invokeSupperCache.remove(pluginId); registryInfo.remove(pluginId); - super.stop(pluginInsideInfo); + super.stop(pluginInsideInfo, closeType); } catch (Exception e){ if(e instanceof PluginProhibitStopException){ // 禁止停止时, 不设置插件状态 diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginState.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginState.java index ff124587b2945e241a6f7209359130f954746090..1af14d03f0a5e07006c49f1b61693e95ac327673 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginState.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginState.java @@ -51,7 +51,12 @@ public enum PluginState { /** * 停止失败状态 */ - STOPPED_FAILURE("STOPPED_FAILURE"); + STOPPED_FAILURE("STOPPED_FAILURE"), + + /** + * 被解析状态. 仅仅用于解析插件后被展示的状态 + */ + PARSED("PARSED"); private final String status; diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java index c993535f446a09dc989a1dd7529bdc444eb8ea41..e8206bfbef7b2a47c1e72a933c06d23668f42405 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.classloader; +import com.gitee.starblues.loader.utils.IOUtils; import com.gitee.starblues.utils.ObjectUtils; import java.util.ArrayList; @@ -27,7 +28,7 @@ import java.util.List; * @author starBlues * @version 3.0.3 */ -public class ComposeMainResourceMatcher implements MainResourceMatcher{ +public class ComposeMainResourceMatcher implements MainResourceMatcher, AutoCloseable{ private final List resourceMatchers; @@ -59,4 +60,13 @@ public class ComposeMainResourceMatcher implements MainResourceMatcher{ } return Boolean.FALSE; } + + @Override + public void close() throws Exception { + for (MainResourceMatcher resourceMatcher : resourceMatchers) { + if(resourceMatcher instanceof AutoCloseable){ + IOUtils.closeQuietly((AutoCloseable)resourceMatcher); + } + } + } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/NestedPluginJarResourceLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/NestedPluginJarResourceLoader.java index 79b393e676b851654788cc9ffb5e66babe9e6203..c09c2ccc808df814f4a5d0f5ac9ae506dabf6a46 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/NestedPluginJarResourceLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/NestedPluginJarResourceLoader.java @@ -23,8 +23,9 @@ import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.loader.classloader.*; import com.gitee.starblues.loader.classloader.resource.loader.*; import com.gitee.starblues.loader.classloader.resource.storage.ResourceStorage; -import com.gitee.starblues.loader.launcher.ResourceLoaderFactoryGetter; +import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.MsgUtils; +import com.gitee.starblues.utils.ObjectUtils; import lombok.extern.slf4j.Slf4j; import java.io.InputStream; @@ -39,23 +40,28 @@ import java.util.zip.ZipEntry; /** * 嵌套插件jar加载者 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ @Slf4j public class NestedPluginJarResourceLoader extends AbstractResourceLoader { private final InsidePluginDescriptor pluginDescriptor; - private final GenericClassLoader parentClassLoader; private final ResourceLoaderFactory resourceLoaderFactory; - + private final ResourceLoaderFactory parentResourceLoaderFactory; public NestedPluginJarResourceLoader(InsidePluginDescriptor pluginDescriptor, - GenericClassLoader parentClassLoader, ResourceLoaderFactory resourceLoaderFactory) throws Exception { + this(pluginDescriptor, resourceLoaderFactory, null); + } + + public NestedPluginJarResourceLoader(InsidePluginDescriptor pluginDescriptor, + ResourceLoaderFactory resourceLoaderFactory, + ResourceLoaderFactory parentResourceLoaderFactory) throws Exception { super(new URL("jar:" + pluginDescriptor.getInsidePluginPath().toUri().toURL() + "!/")); this.pluginDescriptor = pluginDescriptor; - this.parentClassLoader = parentClassLoader; this.resourceLoaderFactory = resourceLoaderFactory; + this.parentResourceLoaderFactory = parentResourceLoaderFactory; } @Override @@ -76,6 +82,7 @@ public class NestedPluginJarResourceLoader extends AbstractResourceLoader { } String realName = jarEntry.getName().replace(classesPath, ""); URL url = new URL(baseUrl.toString() + jarEntry.getName()); + resourceLoaderFactory.addResource(new DefaultResource(realName, baseUrl, url)); resourceStorage.add(realName, url, ()->{ return getClassBytes(realName, jarFile.getInputStream(jarEntry), true); }); @@ -87,7 +94,8 @@ public class NestedPluginJarResourceLoader extends AbstractResourceLoader { Set pluginLibInfos = pluginDescriptor.getPluginLibInfo(); String pluginUnique = MsgUtils.getPluginUnique(pluginDescriptor); for (PluginLibInfo pluginLibInfo : pluginLibInfos) { - jarEntry = jarFile.getJarEntry(pluginLibInfo.getPath()); + String entryName = pluginLibInfo.getPath(); + jarEntry = jarFile.getJarEntry(entryName); if(jarEntry == null){ log.debug("Not found: " + pluginLibInfo.getPath()); continue; @@ -97,8 +105,8 @@ public class NestedPluginJarResourceLoader extends AbstractResourceLoader { } InputStream jarFileInputStream = jarFile.getInputStream(jarEntry); URL url = new URL(baseUrl.toString() + pluginLibInfo.getPath() + "!/"); - if(pluginLibInfo.isLoadToMain()){ - parentClassLoader.addResource(new JarResourceLoader(url, new JarInputStream(jarFileInputStream))); + if(parentResourceLoaderFactory != null && pluginLibInfo.isLoadToMain()){ + parentResourceLoaderFactory.addResource(new JarResourceLoader(url, new JarInputStream(jarFileInputStream))); log.debug("插件[{}]依赖被加载到主程序中: {}", pluginUnique, pluginLibInfo.getPath()); } else { JarResourceLoader jarResourceLoader = new JarResourceLoader(url, new JarInputStream(jarFileInputStream)); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginClassLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginClassLoader.java index c94681e52f554388066a8ab85c9b1c5187871778..11ab94c518bb4b0df8e8bc99e590e8cc98521e2a 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginClassLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginClassLoader.java @@ -21,7 +21,9 @@ import com.gitee.starblues.core.descriptor.PluginLibInfo; import com.gitee.starblues.core.descriptor.PluginType; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.loader.classloader.*; +import com.gitee.starblues.loader.classloader.resource.Resource; import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; +import com.gitee.starblues.loader.utils.IOUtils; import com.gitee.starblues.utils.Assert; import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.MsgUtils; @@ -39,90 +41,28 @@ import java.util.Set; * 插件 classLoader * @author starBlues * @version 3.0.3 + * @since 3.0.0 */ @Slf4j -public class PluginClassLoader extends GenericClassLoader { +public class PluginClassLoader extends GenericClassLoader implements PluginResourceLoaderFactory{ - private final GenericClassLoader parentClassLoader; private final MainResourceMatcher mainResourceMatcher; + private final PluginResourceLoaderFactory proxy; + public PluginClassLoader(String name, GenericClassLoader parentClassLoader, ResourceLoaderFactory resourceLoaderFactory, MainResourceMatcher mainResourceMatcher) { super(name, parentClassLoader, resourceLoaderFactory); - this.parentClassLoader = parentClassLoader; this.mainResourceMatcher = mainResourceMatcher; + this.proxy = new PluginResourceLoaderFactoryProxy(resourceLoaderFactory, parentClassLoader); } - public MainResourceMatcher getMainResourceMatcher() { - return mainResourceMatcher; - } - + @Override public void addResource(InsidePluginDescriptor descriptor) throws Exception { - PluginType pluginType = descriptor.getType(); - if(PluginType.isNestedPackage(pluginType)){ - NestedPluginJarResourceLoader resourceLoader = - new NestedPluginJarResourceLoader(descriptor, parentClassLoader, resourceLoaderFactory); - resourceLoaderFactory.addResource(resourceLoader); - } else if(PluginType.isOuterPackage(pluginType)){ - addOuterPluginClasspath(descriptor); - addLibFile(descriptor); - } else { - addDirPluginClasspath(descriptor); - addLibFile(descriptor); - } - } - - private void addOuterPluginClasspath(InsidePluginDescriptor descriptor) throws Exception{ - String pluginPath = descriptor.getPluginPath(); - File existFile = FilesUtils.getExistFile(pluginPath); - if(existFile != null){ - addResource(existFile); - log.debug("插件[{}]Classpath已被加载: {}", MsgUtils.getPluginUnique(descriptor), existFile.getPath()); - } else { - throw new PluginException("没有发现插件路径: " + pluginPath); - } - } - - private void addDirPluginClasspath(InsidePluginDescriptor descriptor) throws Exception { - String pluginClassPath = descriptor.getPluginClassPath(); - File existFile = FilesUtils.getExistFile(pluginClassPath); - if(existFile != null){ - addResource(existFile); - log.debug("插件[{}]Classpath已被加载: {}", MsgUtils.getPluginUnique(descriptor), existFile.getPath()); - } - } - - private void addLibFile(InsidePluginDescriptor pluginDescriptor) throws Exception { - Set pluginLibInfos = pluginDescriptor.getPluginLibInfo(); - if(ObjectUtils.isEmpty(pluginLibInfos)){ - return; - } - String pluginUnique = MsgUtils.getPluginUnique(pluginDescriptor); - String pluginLibDir = pluginDescriptor.getPluginLibDir(); - if(!ObjectUtils.isEmpty(pluginLibDir)){ - log.info("插件[{}]依赖加载目录: {}", pluginUnique, pluginLibDir); - } - if(pluginLibInfos.isEmpty()){ - log.warn("插件[{}]依赖为空!", pluginUnique); - return; - } - for (PluginLibInfo pluginLibInfo : pluginLibInfos) { - File existFile = FilesUtils.getExistFile(pluginLibInfo.getPath()); - if(existFile != null){ - if(pluginLibInfo.isLoadToMain()){ - // 加载到主程序中 - parentClassLoader.addResource(existFile); - log.debug("插件[{}]依赖被加载到主程序中: {}", pluginUnique, existFile.getPath()); - } else { - addResource(existFile); - log.debug("插件[{}]依赖被加载: {}", pluginUnique, existFile.getPath()); - } - } - } + proxy.addResource(descriptor); } - @Override protected Class findClassFromParent(String className) throws ClassNotFoundException { if(mainResourceMatcher.match(className.replace(".", "/"))){ @@ -175,4 +115,5 @@ public class PluginClassLoader extends GenericClassLoader { } } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginGeneralUrlClassLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginGeneralUrlClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..1326662d8c65b9d8d569e75ce3bda8a742551430 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginGeneralUrlClassLoader.java @@ -0,0 +1,52 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.core.classloader; + +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.loader.classloader.GeneralUrlClassLoader; +import com.gitee.starblues.loader.utils.IOUtils; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; + +/** + * 插件基本 url classLoader + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +@Slf4j +public class PluginGeneralUrlClassLoader extends GeneralUrlClassLoader implements PluginResourceLoaderFactory{ + + private final PluginResourceLoaderFactory proxy; + + public PluginGeneralUrlClassLoader(String name, GeneralUrlClassLoader parent) { + super(name, parent); + this.proxy = new PluginResourceLoaderFactoryProxy(this, parent); + } + + @Override + public void addResource(InsidePluginDescriptor descriptor) throws Exception { + proxy.addResource(descriptor); + } + + @Override + public void close() throws IOException { + super.close(); + } +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactory.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..3be839a39c608c32040a244166bc2174bac1f2db --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactory.java @@ -0,0 +1,40 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.core.classloader; + +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; + +/** + * 插件资源工程 + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public interface PluginResourceLoaderFactory extends ResourceLoaderFactory { + + /** + * 加载插件资源 + * @param descriptor 插件资源描述 + * @throws Exception 添加插件资源异常 + * @since 3.0.4 + */ + void addResource(InsidePluginDescriptor descriptor) throws Exception; + + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactoryProxy.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactoryProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..10143b86ea6b90afaa8b01b3c5df2209caffb7a2 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/PluginResourceLoaderFactoryProxy.java @@ -0,0 +1,182 @@ +/** + * Copyright [2019-2022] [starBlues] + * + * 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.gitee.starblues.core.classloader; + +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.descriptor.PluginLibInfo; +import com.gitee.starblues.core.descriptor.PluginType; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.loader.classloader.resource.Resource; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoader; +import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.MsgUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.List; +import java.util.Set; + +/** + * 插件资源加载工厂代理 + * + * @author starBlues + * @version 3.1.0 + * @since 13.0.4 + */ +@Slf4j +public class PluginResourceLoaderFactoryProxy implements PluginResourceLoaderFactory { + + private final ResourceLoaderFactory target; + private final ResourceLoaderFactory parent; + + public PluginResourceLoaderFactoryProxy(ResourceLoaderFactory target) { + this(target, null); + } + + public PluginResourceLoaderFactoryProxy(ResourceLoaderFactory target, ResourceLoaderFactory parent) { + this.target = target; + this.parent = parent; + } + + @Override + public void addResource(InsidePluginDescriptor descriptor) throws Exception { + PluginType pluginType = descriptor.getType(); + if(PluginType.isNestedPackage(pluginType)){ + NestedPluginJarResourceLoader resourceLoader = + new NestedPluginJarResourceLoader(descriptor, target, parent); + target.addResource(resourceLoader); + } else if(PluginType.isOuterPackage(pluginType)){ + addOuterPluginClasspath(descriptor); + addLibFile(descriptor); + } else { + addDirPluginClasspath(descriptor); + addLibFile(descriptor); + } + } + + private void addOuterPluginClasspath(InsidePluginDescriptor descriptor) throws Exception{ + String pluginPath = descriptor.getPluginPath(); + File existFile = FilesUtils.getExistFile(pluginPath); + if(existFile != null){ + addResource(existFile); + log.debug("插件[{}]Classpath已被加载: {}", MsgUtils.getPluginUnique(descriptor), existFile.getPath()); + } else { + throw new PluginException("没有发现插件路径: " + pluginPath); + } + } + + private void addDirPluginClasspath(InsidePluginDescriptor descriptor) throws Exception { + String pluginClassPath = descriptor.getPluginClassPath(); + File existFile = FilesUtils.getExistFile(pluginClassPath); + if(existFile != null){ + addResource(existFile); + log.debug("插件[{}]Classpath已被加载: {}", MsgUtils.getPluginUnique(descriptor), existFile.getPath()); + } + } + + + private void addLibFile(InsidePluginDescriptor pluginDescriptor) throws Exception { + Set pluginLibInfos = pluginDescriptor.getPluginLibInfo(); + if(ObjectUtils.isEmpty(pluginLibInfos)){ + return; + } + String pluginUnique = MsgUtils.getPluginUnique(pluginDescriptor); + String pluginLibDir = pluginDescriptor.getPluginLibDir(); + if(!ObjectUtils.isEmpty(pluginLibDir)){ + log.info("插件[{}]依赖加载目录: {}", pluginUnique, pluginLibDir); + } + if(pluginLibInfos.isEmpty()){ + log.warn("插件[{}]依赖为空!", pluginUnique); + return; + } + for (PluginLibInfo pluginLibInfo : pluginLibInfos) { + File existFile = FilesUtils.getExistFile(pluginLibInfo.getPath()); + if(existFile != null){ + if(pluginLibInfo.isLoadToMain()){ + // 加载到主程序中 + parent.addResource(existFile); + log.debug("插件[{}]依赖被加载到主程序中: {}", pluginUnique, existFile.getPath()); + } else { + target.addResource(existFile); + log.debug("插件[{}]依赖被加载: {}", pluginUnique, existFile.getPath()); + } + } + } + } + + + @Override + public void addResource(String path) throws Exception { + target.addResource(path); + } + + @Override + public void addResource(File file) throws Exception { + target.addResource(file); + } + + @Override + public void addResource(Path path) throws Exception { + target.addResource(path); + } + + @Override + public void addResource(URL url) throws Exception { + target.addResource(url); + } + + @Override + public void addResource(Resource resource) throws Exception { + target.addResource(resource); + } + + @Override + public void addResource(ResourceLoader resourceLoader) throws Exception { + target.addResource(resourceLoader); + } + + @Override + public Resource findFirstResource(String name) { + return target.findFirstResource(name); + } + + @Override + public Enumeration findAllResource(String name) { + return target.findAllResource(name); + } + + @Override + public InputStream getInputStream(String name) { + return target.getInputStream(name); + } + + @Override + public List getUrls() { + return target.getUrls(); + } + + @Override + public void close() throws Exception { + target.close(); + } +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java index 3f7bd7362d53942ecdf36f1643071fa3d88d2cec..efeb3a0e72e4c0a36526012821e08a7e1f38194d 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java @@ -48,7 +48,8 @@ import static com.gitee.starblues.utils.PropertiesUtils.getValue; /** * 抽象的 PluginDescriptorLoader * @author starBlues - * @version 3.0.2 + * @since 3.0.0 + * @version 3.1.0 */ @Slf4j public abstract class AbstractPluginDescriptorLoader implements PluginDescriptorLoader{ @@ -155,11 +156,14 @@ public abstract class AbstractPluginDescriptorLoader implements PluginDescriptor } protected Set getPluginLibInfo(DefaultInsidePluginDescriptor descriptor, Set dependenciesIndex){ - String pluginLibDir = descriptor.getPluginLibDir(); - boolean configPluginLibDir = false; - if(!ObjectUtils.isEmpty(pluginLibDir)){ - descriptor.setPluginLibDir(getLibDir(descriptor, pluginLibDir)); - configPluginLibDir = true; + String configPluginLibDir = descriptor.getPluginLibDir(); + boolean isConfigPluginLibDir = false; + if(!ObjectUtils.isEmpty(configPluginLibDir)){ + String libDir = getLibDir(descriptor, configPluginLibDir); + if(!ObjectUtils.isEmpty(libDir)){ + descriptor.setPluginLibDir(libDir); + isConfigPluginLibDir = true; + } } if(ObjectUtils.isEmpty(dependenciesIndex)){ return Collections.emptySet(); @@ -174,8 +178,8 @@ public abstract class AbstractPluginDescriptorLoader implements PluginDescriptor loadToMain = false; } String libPath = index; - if(configPluginLibDir){ - libPath = getLibPath(descriptor, index); + if(isConfigPluginLibDir){ + libPath = getLibPath(descriptor, configPluginLibDir, index); } pluginLibInfos.add(new PluginLibInfo(libPath, loadToMain)); } @@ -183,31 +187,49 @@ public abstract class AbstractPluginDescriptorLoader implements PluginDescriptor } protected String getLibDir(DefaultInsidePluginDescriptor descriptor, String configPluginLibDir){ - if(!FilesUtils.isRelativePath(configPluginLibDir)){ + if(FilesUtils.existFile(configPluginLibDir)){ return configPluginLibDir; } - // 是相对路径 - // 先相对当前插件目录 - String resolveRelativePath = FilesUtils.resolveRelativePath(descriptor.getPluginPath(), configPluginLibDir); - if(new File(resolveRelativePath).exists()){ + // 先检查插件相对目录 + String resolveRelativePath = null; + if(FilesUtils.isRelativePath(configPluginLibDir)){ + // 先相对当前插件目录 + resolveRelativePath = FilesUtils.resolveRelativePath(descriptor.getPluginPath(), configPluginLibDir); + } else { + resolveRelativePath = FilesUtils.joiningFilePath(descriptor.getPluginPath(), configPluginLibDir); + } + if(FilesUtils.existFile(resolveRelativePath)){ return resolveRelativePath; } // 再相对插件存放目录 - resolveRelativePath = FilesUtils.resolveRelativePath(new File(descriptor.getPluginPath()).getParent(), configPluginLibDir); - if(new File(resolveRelativePath).exists()){ + resolveRelativePath = FilesUtils.joiningFilePath(new File(descriptor.getPluginPath()).getParent(), configPluginLibDir); + if(FilesUtils.existFile(resolveRelativePath)){ return resolveRelativePath; } // 最后相对主程序目录 - resolveRelativePath = FilesUtils.resolveRelativePath(new File("").getAbsolutePath(), configPluginLibDir); - if(new File(resolveRelativePath).exists()){ + resolveRelativePath = FilesUtils.joiningFilePath(new File("").getAbsolutePath(), configPluginLibDir); + if(FilesUtils.existFile(resolveRelativePath)){ return resolveRelativePath; } - throw new PluginException("插件["+ MsgUtils.getPluginUnique(descriptor) +"]" + - "依赖目录[" + descriptor.getPluginLibDir() + "]不存在!"); + return null; } - protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String index){ - return FilesUtils.joiningFilePath(descriptor.getPluginLibDir(), index); + protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String configPluginLibDir, String index){ + String pluginLibDir = descriptor.getPluginLibDir(); + if(ObjectUtils.isEmpty(pluginLibDir)){ + return index; + } + String joiningFilePath = FilesUtils.joiningFilePath(descriptor.getPluginLibDir(), index); + if(index.startsWith(configPluginLibDir)){ + // 如果 index 中前缀配置了 PLUGIN.META 中的 plugin.libDir 则尝试判断完整拼接的依赖路径文件是否存在 + // 如果存在, 则返回, 如果不存在, 则去掉重复前缀, 返回。该处是为了兼容解压后的jar中index存在 libDir 前缀 + if(FilesUtils.existFile(joiningFilePath)){ + return joiningFilePath; + } + return FilesUtils.joiningFilePath(descriptor.getPluginLibDir(), + index.replace(configPluginLibDir, "")); + } + return joiningFilePath; } protected Properties getDecryptProperties(InputStream inputStream) throws Exception{ diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java index 432e9fc1146831097d8fbbb15e9efcdfb0478ece..f7591775c063fdae5756274093c9f2387938d0f0 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java @@ -58,7 +58,7 @@ public class DevPluginDescriptorLoader extends AbstractPluginDescriptorLoader{ } @Override - protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String index) { + protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String configPluginLibDir, String index) { return index; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java index 4721da36c8fc7cf426878116e87ac8460c2e0204..a52b8a6cd3aa7f853c052011f50315f358ec16b7 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java @@ -42,7 +42,8 @@ import static com.gitee.starblues.common.PluginDescriptorKey.PLUGIN_RESOURCES_CO * 生产环境打包好的插件 PluginDescriptorLoader 加载者 * 解析 jar、zip * @author starBlues - * @version 3.0.2 + * @since 3.0.0 + * @version 3.1.0 */ public class ProdPackagePluginDescriptorLoader extends AbstractPluginDescriptorLoader{ @@ -90,11 +91,19 @@ public class ProdPackagePluginDescriptorLoader extends AbstractPluginDescriptorL } @Override - protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String index) { + protected String getLibPath(DefaultInsidePluginDescriptor descriptor, String configPluginLibDir, String index) { if(PluginType.isNestedPackage(descriptor.getType())){ - return index; + String pluginLibDir = descriptor.getPluginLibDir(); + if(ObjectUtils.isEmpty(pluginLibDir)){ + return index; + } + if(index.startsWith(configPluginLibDir)){ + // 兼容解决旧版本中 jar/zip 包中, 依赖前缀携带 配置的 lib 路径 + return index; + } + return FilesUtils.joiningZipPath(pluginLibDir, index); } else { - return super.getLibPath(descriptor, index); + return super.getLibPath(descriptor, configPluginLibDir, index); } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultPluginInteractive.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultPluginInteractive.java index c26810d10eef2fccf120bb40d96a55e59bd365b0..a9249b830ca748e4569e53bafd956fd9336756f3 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultPluginInteractive.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultPluginInteractive.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.launcher.plugin; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.spring.MainApplicationContext; @@ -31,17 +32,17 @@ import com.gitee.starblues.spring.invoke.InvokeSupperCache; */ public class DefaultPluginInteractive implements PluginInteractive{ - private final InsidePluginDescriptor pluginDescriptor; + private final PluginInsideInfo pluginInsideInfo; private final MainApplicationContext mainApplicationContext; private final IntegrationConfiguration configuration; private final InvokeSupperCache invokeSupperCache; private final OpExtractFactory opExtractFactory; - public DefaultPluginInteractive(InsidePluginDescriptor pluginDescriptor, + public DefaultPluginInteractive(PluginInsideInfo pluginInsideInfo, MainApplicationContext mainApplicationContext, IntegrationConfiguration configuration, InvokeSupperCache invokeSupperCache) { - this.pluginDescriptor = pluginDescriptor; + this.pluginInsideInfo = pluginInsideInfo; this.mainApplicationContext = mainApplicationContext; this.configuration = configuration; this.invokeSupperCache = invokeSupperCache; @@ -53,10 +54,14 @@ public class DefaultPluginInteractive implements PluginInteractive{ return (OpExtractFactory) defaultExtractFactory.getTarget(); } - @Override public InsidePluginDescriptor getPluginDescriptor() { - return pluginDescriptor; + return pluginInsideInfo.getPluginDescriptor(); + } + + @Override + public PluginInsideInfo getPluginInsideInfo() { + return pluginInsideInfo; } @Override diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginCoexistLauncher.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginCoexistLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..3bb4d27d308ba0c58a56996d5fca42320a8a148d --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginCoexistLauncher.java @@ -0,0 +1,79 @@ +package com.gitee.starblues.core.launcher.plugin; + +import com.gitee.starblues.core.PluginInsideInfo; +import com.gitee.starblues.core.classloader.NestedPluginJarResourceLoader; +import com.gitee.starblues.core.classloader.PluginGeneralUrlClassLoader; +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.descriptor.PluginLibInfo; +import com.gitee.starblues.core.descriptor.PluginType; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; +import com.gitee.starblues.loader.classloader.GeneralUrlClassLoader; +import com.gitee.starblues.loader.launcher.AbstractLauncher; +import com.gitee.starblues.loader.launcher.LauncherContext; +import com.gitee.starblues.spring.SpringPluginHook; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.MsgUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.util.Set; + +/** + * 插件共享式启动引导 + * + * @author starBlues + * @since 3.0.4 + * @version 3.1.0 + */ +@Slf4j +public class PluginCoexistLauncher extends AbstractLauncher { + + protected final PluginInteractive pluginInteractive; + protected final PluginLaunchInvolved pluginLaunchInvolved; + + public PluginCoexistLauncher(PluginInteractive pluginInteractive, + PluginLaunchInvolved pluginLaunchInvolved) { + this.pluginInteractive = pluginInteractive; + this.pluginLaunchInvolved = pluginLaunchInvolved; + } + + @Override + protected ClassLoader createClassLoader(String... args) throws Exception { + PluginGeneralUrlClassLoader classLoader = new PluginGeneralUrlClassLoader( + pluginInteractive.getPluginDescriptor().getPluginId(), + getParentClassLoader()); + classLoader.addResource(pluginInteractive.getPluginDescriptor()); + return classLoader; + } + + @Override + protected SpringPluginHook launch(ClassLoader classLoader, String... args) throws Exception { + InsidePluginDescriptor pluginDescriptor = pluginInteractive.getPluginDescriptor(); + PluginInsideInfo pluginInsideInfo = pluginInteractive.getPluginInsideInfo(); + pluginLaunchInvolved.before(pluginInsideInfo, classLoader); + try { + SpringPluginHook springPluginHook = (SpringPluginHook) new PluginMethodRunner(pluginInteractive) + .run(classLoader); + if(springPluginHook == null){ + throw new PluginException("插件返回的 SpringPluginHook 不能为空"); + } + pluginLaunchInvolved.after(pluginInsideInfo, classLoader, springPluginHook); + return new SpringPluginHookWrapper(springPluginHook, pluginInsideInfo, pluginLaunchInvolved, classLoader); + } catch (Throwable throwable){ + pluginLaunchInvolved.failure(pluginInsideInfo,classLoader, throwable); + throw throwable; + } + } + + protected GeneralUrlClassLoader getParentClassLoader() throws Exception { + ClassLoader contextClassLoader = LauncherContext.getMainClassLoader(); + if(contextClassLoader instanceof GeneralUrlClassLoader){ + return (GeneralUrlClassLoader) contextClassLoader; + } else { + throw new Exception("非法父类加载器: " + contextClassLoader.getClass().getName()); + } + } + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginInteractive.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginInteractive.java index e9e87e1c86f82f87826d15728b317d059bbab5eb..2278ca55740455e47a0b26ee4622bdc02942f0e5 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginInteractive.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginInteractive.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.launcher.plugin; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.spring.MainApplicationContext; @@ -35,6 +36,12 @@ public interface PluginInteractive { */ InsidePluginDescriptor getPluginDescriptor(); + /** + * 获取插件内部信息 + * @return PluginInsideInfo + */ + PluginInsideInfo getPluginInsideInfo(); + /** * 获取主程序的 MainApplicationContext * @return MainApplicationContext diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginIsolationLauncher.java similarity index 81% rename from spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java rename to spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginIsolationLauncher.java index 8ff0e503409bb1e1cb1bbd559ee63533322d0ccc..90412335992ab5751b9f63b311fb7feab68baaf1 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginIsolationLauncher.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.launcher.plugin; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.classloader.*; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; @@ -35,24 +36,26 @@ import java.util.Map; import java.util.WeakHashMap; /** - * 插件启动引导类 + * 插件隔离式启动引导 + * * @author starBlues - * @version 3.0.3 + * @since 3.0.0 + * @version 3.1.0 */ -public class PluginLauncher extends AbstractLauncher { +public class PluginIsolationLauncher extends AbstractLauncher { private static final Map CLASS_LOADER_CACHE = new WeakHashMap<>(); protected final PluginInteractive pluginInteractive; - protected final InsidePluginDescriptor pluginDescriptor; + protected final PluginInsideInfo pluginInsideInfo; protected final MainResourceMatcher mainResourceMatcher; protected final PluginLaunchInvolved pluginLaunchInvolved; - public PluginLauncher(PluginInteractive pluginInteractive, - PluginLaunchInvolved pluginLaunchInvolved) { + public PluginIsolationLauncher(PluginInteractive pluginInteractive, + PluginLaunchInvolved pluginLaunchInvolved) { this.pluginInteractive = pluginInteractive; - this.pluginDescriptor = pluginInteractive.getPluginDescriptor(); + this.pluginInsideInfo = pluginInteractive.getPluginInsideInfo(); this.mainResourceMatcher = getMainResourceMatcher(pluginInteractive); this.pluginLaunchInvolved = pluginLaunchInvolved; } @@ -74,13 +77,13 @@ public class PluginLauncher extends AbstractLauncher { @Override protected ClassLoader createClassLoader(String... args) throws Exception { PluginClassLoader pluginClassLoader = getPluginClassLoader(); - pluginClassLoader.addResource(pluginDescriptor); + pluginClassLoader.addResource(pluginInsideInfo.getPluginDescriptor()); return pluginClassLoader; } protected synchronized PluginClassLoader getPluginClassLoader() throws Exception { - String pluginId = pluginDescriptor.getPluginId(); - String key = MsgUtils.getPluginUnique(pluginDescriptor); + String pluginId = pluginInsideInfo.getPluginId(); + String key = MsgUtils.getPluginUnique(pluginInsideInfo.getPluginDescriptor()); PluginClassLoader classLoader = CLASS_LOADER_CACHE.get(key); if(classLoader != null){ return classLoader; @@ -93,7 +96,7 @@ public class PluginLauncher extends AbstractLauncher { } protected ResourceLoaderFactory getResourceLoaderFactory(){ - return new DefaultResourceLoaderFactory(pluginDescriptor.getPluginId()); + return new DefaultResourceLoaderFactory(pluginInsideInfo.getPluginId()); } protected GenericClassLoader getParentClassLoader() throws Exception { @@ -107,17 +110,16 @@ public class PluginLauncher extends AbstractLauncher { @Override protected SpringPluginHook launch(ClassLoader classLoader, String... args) throws Exception { - pluginLaunchInvolved.before(pluginDescriptor, classLoader); + pluginLaunchInvolved.before(pluginInsideInfo, classLoader); try { SpringPluginHook springPluginHook = (SpringPluginHook) new PluginMethodRunner(pluginInteractive) .run(classLoader); - pluginLaunchInvolved.after(pluginDescriptor, classLoader, springPluginHook); - return new SpringPluginHookWrapper(springPluginHook, pluginDescriptor, pluginLaunchInvolved, classLoader); + pluginLaunchInvolved.after(pluginInsideInfo, classLoader, springPluginHook); + return new SpringPluginHookWrapper(springPluginHook, pluginInsideInfo, pluginLaunchInvolved, classLoader); } catch (Throwable throwable){ - pluginLaunchInvolved.failure(pluginDescriptor,classLoader, throwable); + pluginLaunchInvolved.failure(pluginInsideInfo,classLoader, throwable); throw throwable; } } - } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java index e25ac5fa8f31549cea02a6c26fa25175d2b0827c..a2c6b95f6569f39500e31d66cf7cb5cd03ae26bb 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java @@ -16,7 +16,8 @@ package com.gitee.starblues.core.launcher.plugin; -import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.PluginCloseType; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.exception.PluginProhibitStopException; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; import com.gitee.starblues.spring.ApplicationContext; @@ -24,24 +25,27 @@ import com.gitee.starblues.spring.SpringPluginHook; import com.gitee.starblues.spring.WebConfig; import com.gitee.starblues.spring.web.thymeleaf.ThymeleafConfig; import com.gitee.starblues.utils.ResourceUtils; +import lombok.extern.slf4j.Slf4j; /** * SpringPluginHook-Wrapper * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ +@Slf4j public class SpringPluginHookWrapper implements SpringPluginHook { private final SpringPluginHook target; - private final InsidePluginDescriptor descriptor; + private final PluginInsideInfo pluginInsideInfo; private final PluginLaunchInvolved pluginLaunchInvolved; private final ClassLoader classLoader; - public SpringPluginHookWrapper(SpringPluginHook target, InsidePluginDescriptor descriptor, + public SpringPluginHookWrapper(SpringPluginHook target, PluginInsideInfo pluginInsideInfo, PluginLaunchInvolved pluginLaunchInvolved, ClassLoader classLoader) { this.target = target; - this.descriptor = descriptor; + this.pluginInsideInfo = pluginInsideInfo; this.pluginLaunchInvolved = pluginLaunchInvolved; this.classLoader = classLoader; } @@ -67,9 +71,16 @@ public class SpringPluginHookWrapper implements SpringPluginHook { } @Override - public void close() throws Exception { - pluginLaunchInvolved.close(descriptor, classLoader); - ResourceUtils.closeQuietly(target); - ResourceUtils.closeQuietly(classLoader); + public void close(PluginCloseType closeType) throws Exception { + try { + pluginLaunchInvolved.close(pluginInsideInfo, classLoader); + } catch (Exception e){ + log.error("关闭插件异常: {}", e.getMessage(), e); + } + try { + target.close(closeType); + } finally { + ResourceUtils.closeQuietly(classLoader); + } } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java index 33fee5b7d1789116f691e7fb02ff849969cac8d1..4e25965d05cde366b9ff971580bd6fbf637f278e 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java @@ -16,32 +16,73 @@ package com.gitee.starblues.core.launcher.plugin.involved; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.PluginExtensionInfo; import com.gitee.starblues.loader.PluginResourceStorage; +import com.gitee.starblues.spring.ApplicationContext; import com.gitee.starblues.spring.SpringPluginHook; import com.gitee.starblues.spring.web.PluginStaticResourceResolver; +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.SpringBeanCustomUtils; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 默认的插件启动介入者 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ +@Slf4j public class DefaultPluginLaunchInvolved implements PluginLaunchInvolved{ @Override - public void before(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { + public void before(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); PluginResourceStorage.addPlugin(descriptor.getPluginId(), descriptor.getPluginFileName()); } @Override - public void after(InsidePluginDescriptor descriptor, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + public void after(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); PluginStaticResourceResolver.parse(descriptor, classLoader, pluginHook.getWebConfig()); + setExtensionInfoSupplier(pluginInsideInfo, pluginHook); } @Override - public void close(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { + public void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); String pluginId = descriptor.getPluginId(); PluginResourceStorage.removePlugin(pluginId); PluginStaticResourceResolver.remove(pluginId); } + + private void setExtensionInfoSupplier(PluginInsideInfo pluginInsideInfo, SpringPluginHook pluginHook){ + pluginInsideInfo.setExtensionInfoSupplier(()->{ + // 设置插件自主扩展信息 + ApplicationContext applicationContext = pluginHook.getApplicationContext(); + List beans = SpringBeanCustomUtils.getBeans(applicationContext, + PluginExtensionInfo.class); + if(ObjectUtils.isEmpty(beans)){ + return new HashMap<>(0); + } + Map extensionInfos = new HashMap<>(); + for (PluginExtensionInfo extensionInfoBean : beans) { + try { + Map extensionInfo = extensionInfoBean.extensionInfo(); + if(!ObjectUtils.isEmpty(extensionInfo)){ + extensionInfos.putAll(extensionInfo); + } + } catch (Exception e){ + log.error(e.getMessage(), e); + } + } + return extensionInfos; + }); + } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginApplicationContextGetter.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginApplicationContextGetter.java index 8a8754ebf554d05543217d2a1d576b82e01ce992..165db50b1ab748175ec892f6f035c9a4762537db 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginApplicationContextGetter.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginApplicationContextGetter.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.launcher.plugin.involved; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.spring.ApplicationContext; import com.gitee.starblues.spring.SpringPluginHook; @@ -25,19 +26,22 @@ import java.util.concurrent.ConcurrentHashMap; /** * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public class PluginApplicationContextGetter implements PluginLaunchInvolved{ private static final Map PLUGIN_CONTEXTS = new ConcurrentHashMap<>(); @Override - public void after(InsidePluginDescriptor descriptor, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + public void after(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); PLUGIN_CONTEXTS.put(descriptor.getPluginId(), pluginHook.getApplicationContext()); } @Override - public void close(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { + public void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); PLUGIN_CONTEXTS.remove(descriptor.getPluginId()); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolved.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolved.java index 93fc5a1752e807b8e7111d808d841c95a1cb0dd0..5e3bbe641f4ca49d2b6ccfc9d1b9a30d5dd21a80 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolved.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolved.java @@ -16,7 +16,7 @@ package com.gitee.starblues.core.launcher.plugin.involved; -import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.spring.SpringPluginHook; import com.gitee.starblues.utils.OrderPriority; @@ -25,7 +25,8 @@ import org.springframework.context.support.GenericApplicationContext; /** * 插件启动前后介入 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public interface PluginLaunchInvolved { @@ -38,38 +39,38 @@ public interface PluginLaunchInvolved { /** * 启动之前 - * @param descriptor 插件信息 + * @param pluginInsideInfo 插件信息 * @param classLoader 插件classloader * @throws Exception 执行异常 */ - default void before(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception{} + default void before(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception{} /** * 启动之后 - * @param descriptor 插件信息 + * @param pluginInsideInfo 插件信息 * @param classLoader 插件classloader * @param pluginHook 启动成功后插件返回的钩子 * @throws Exception 执行异常 */ - default void after(InsidePluginDescriptor descriptor, ClassLoader classLoader, + default void after(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception{} /** * 启动失败 - * @param descriptor 插件信息 + * @param pluginInsideInfo 插件信息 * @param classLoader 插件classloader * @param throwable 异常信息 * @throws Exception 执行异常 */ - default void failure(InsidePluginDescriptor descriptor, ClassLoader classLoader, Throwable throwable) throws Exception{} + default void failure(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, Throwable throwable) throws Exception{} /** * 关闭的时候 - * @param descriptor 插件信息 + * @param pluginInsideInfo 插件信息 * @param classLoader 插件classloader * @throws Exception 执行异常 */ - default void close(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception{} + default void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception{} /** * 执行顺序 diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolvedFactory.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolvedFactory.java index 8330ce2c49130a40b942ed45e978c4fc0901e613..67bc9cceb4a47855002cadf8883872ca8e31eb78 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolvedFactory.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/PluginLaunchInvolvedFactory.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.launcher.plugin.involved; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.spring.SpringPluginHook; @@ -32,7 +33,8 @@ import java.util.Map; /** * 插件启动介入工厂 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public class PluginLaunchInvolvedFactory implements PluginLaunchInvolved{ @@ -75,24 +77,24 @@ public class PluginLaunchInvolvedFactory implements PluginLaunchInvolved{ } @Override - public void before(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { + public void before(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { for (PluginLaunchInvolved pluginLaunchInvolved : pluginLaunchInvolvedList) { - pluginLaunchInvolved.before(descriptor, classLoader); + pluginLaunchInvolved.before(pluginInsideInfo, classLoader); } } @Override - public void after(InsidePluginDescriptor descriptor, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + public void after(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { for (PluginLaunchInvolved pluginLaunchInvolved : pluginLaunchInvolvedList) { - pluginLaunchInvolved.after(descriptor, classLoader, pluginHook); + pluginLaunchInvolved.after(pluginInsideInfo, classLoader, pluginHook); } } @Override - public void failure(InsidePluginDescriptor descriptor, ClassLoader classLoader, Throwable throwable) throws Exception { + public void failure(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, Throwable throwable) throws Exception { for (PluginLaunchInvolved pluginLaunchInvolved : pluginLaunchInvolvedList) { try { - pluginLaunchInvolved.failure(descriptor, classLoader, throwable); + pluginLaunchInvolved.failure(pluginInsideInfo, classLoader, throwable); } catch (Exception e){ logger.error("[{}] execute failure exception : {}", pluginLaunchInvolved.getClass().getName(), e.getMessage(), e); @@ -101,10 +103,10 @@ public class PluginLaunchInvolvedFactory implements PluginLaunchInvolved{ } @Override - public void close(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { + public void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { for (PluginLaunchInvolved pluginLaunchInvolved : pluginLaunchInvolvedList) { try { - pluginLaunchInvolved.close(descriptor, classLoader); + pluginLaunchInvolved.close(pluginInsideInfo, classLoader); } catch (Exception e){ logger.error("[{}] execute close exception : {}", pluginLaunchInvolved.getClass().getName(), e.getMessage(), e); diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java index 79f43b55d80bb4cdfd758404576d175402c7536f..1d0f5d77eac0274d8400b622535f65aa12d3b75f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java @@ -19,6 +19,7 @@ package com.gitee.starblues.integration; import com.gitee.starblues.core.DefaultRealizeProvider; import com.gitee.starblues.core.RealizeProvider;; import com.gitee.starblues.core.classloader.CacheMainResourceMatcher; +import com.gitee.starblues.core.classloader.DefaultMainResourceMatcher; import com.gitee.starblues.core.classloader.MainResourceMatcher; import com.gitee.starblues.core.descriptor.decrypt.DefaultPluginDescriptorDecrypt; import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; @@ -49,6 +50,7 @@ public class ExtendPointConfiguration { IntegrationConfiguration configuration) { this.applicationContext = applicationContext; this.configuration = configuration; + this.configuration.checkConfig(); } @Bean @@ -83,7 +85,7 @@ public class ExtendPointConfiguration { @Bean public MainResourceMatcher mainResourceMatcher(){ - return new CacheMainResourceMatcher(new DefaultMainResourcePatternDefiner( + return new DefaultMainResourceMatcher(new DefaultMainResourcePatternDefiner( configuration.mainPackage(), applicationContext )); diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/SpringBootPluginStarter.java b/spring-brick/src/main/java/com/gitee/starblues/integration/SpringBootPluginStarter.java index bb5289dbf0b060a67fee7bf34b210ed4f72076f7..bf12f778f6c8dcd2054a5b5262f7641c8d1682c9 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/SpringBootPluginStarter.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/SpringBootPluginStarter.java @@ -28,7 +28,6 @@ import org.springframework.context.annotation.Import; * @author starBlues * @version 3.0.0 */ -@Configuration(proxyBeanMethods = true) @EnableConfigurationProperties(AutoIntegrationConfiguration.class) @ConditionalOnExpression("${" + AutoIntegrationConfiguration.ENABLE_STARTER_KEY + ":true}") @Import(AutoPluginApplication.class) diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/application/AutoPluginApplication.java b/spring-brick/src/main/java/com/gitee/starblues/integration/application/AutoPluginApplication.java index 7d1944073e8173a0e9083a8774f4c969debc3be9..3d54fefeb82e2b4658f309734eb579eea0fc13f2 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/application/AutoPluginApplication.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/application/AutoPluginApplication.java @@ -26,6 +26,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Import; +import org.springframework.context.support.GenericApplicationContext; /** * 自动初始化的 PluginApplication。该PluginApplication 基于 Spring InitializingBean 自动初始化插件。 @@ -57,12 +58,16 @@ public class AutoPluginApplication extends DefaultPluginApplication throw new RuntimeException("Cannot be initialized manually"); } - @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } + @Override + protected void setBeanFactory(GenericApplicationContext applicationContext) { + // 忽略 + } + /** * Spring boot bean属性被Set完后调用。会自动初始化插件 */ diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java b/spring-brick/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java index c193dcee4c69e65fb4a56ddf772663826009c8c8..f0c46ce24ab14a3518b45980e81a80d06d2c72ba 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/application/DefaultPluginApplication.java @@ -23,7 +23,6 @@ import com.gitee.starblues.integration.operator.PluginOperator; import com.gitee.starblues.integration.operator.PluginOperatorWrapper; import com.gitee.starblues.integration.user.PluginUser; import com.gitee.starblues.spring.extract.DefaultExtractFactory; -import com.gitee.starblues.spring.extract.DefaultOpExtractFactory; import com.gitee.starblues.spring.extract.ExtractFactory; import com.gitee.starblues.spring.extract.OpExtractFactory; import com.gitee.starblues.utils.ObjectUtils; @@ -150,8 +149,7 @@ public class DefaultPluginApplication extends AbstractPluginApplication { * 直接将 PluginOperator 和 PluginUser 注入到ApplicationContext容器中 * @param applicationContext ApplicationContext */ - @Deprecated - private void setBeanFactory(GenericApplicationContext applicationContext){ + protected void setBeanFactory(GenericApplicationContext applicationContext){ DefaultListableBeanFactory defaultListableBeanFactory = applicationContext.getDefaultListableBeanFactory(); defaultListableBeanFactory.registerSingleton(pluginOperator.getClass().getName(), pluginOperator); defaultListableBeanFactory.registerSingleton(pluginUser.getClass().getName(), pluginUser); diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java index ea44db3699b110f54dcc8140eb0d717afe319726..11e1c827df0312327657f1d1d0b80cb9a4189059 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java @@ -28,6 +28,7 @@ import com.gitee.starblues.integration.listener.PluginInitializerListenerFactory import com.gitee.starblues.integration.operator.upload.UploadByInputStreamParam; import com.gitee.starblues.integration.operator.upload.UploadByMultipartFileParam; import com.gitee.starblues.integration.operator.upload.UploadParam; +import com.gitee.starblues.loader.launcher.DevelopmentModeSetting; import com.gitee.starblues.spring.web.PluginStaticResourceConfig; import com.gitee.starblues.utils.*; import org.apache.commons.io.FileUtils; @@ -53,14 +54,15 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * 默认的插件操作者 * @author starBlues - * @version 3.0.1 + * @version 3.0.0 + * @since 3.0.4 */ public class DefaultPluginOperator implements PluginOperator { protected final Logger log = LoggerFactory.getLogger(this.getClass()); private final static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); - private final AtomicBoolean isInit = new AtomicBoolean(false); + private static final AtomicBoolean IS_INIT = new AtomicBoolean(false); private final GenericApplicationContext applicationContext; private final IntegrationConfiguration configuration; @@ -79,11 +81,12 @@ public class DefaultPluginOperator implements PluginOperator { @Override public synchronized boolean initPlugins(PluginInitializerListener pluginInitializerListener) throws PluginException { - if(isInit.get()){ + if(IS_INIT.get()){ throw new RuntimeException("插件已经被初始化了, 不能再初始化."); } try { log.info("插件加载环境: {}", configuration.environment().toString()); + log.info("插件加载模式: {}", DevelopmentModeSetting.getDevelopmentMode()); pluginInitializerListenerFactory.addListener(pluginInitializerListener); List pluginsRoots = pluginManager.getPluginsRoots(); if(pluginsRoots.isEmpty()){ @@ -114,7 +117,7 @@ public class DefaultPluginOperator implements PluginOperator { isFoundException = true; } } - isInit.set(true); + IS_INIT.set(true); if(isFoundException){ log.error("插件初始化失败"); pluginInitializerListenerFactory.failure(new PluginException("插件初始化存在异常")); diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/EmptyPluginOperator.java b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/EmptyPluginOperator.java new file mode 100644 index 0000000000000000000000000000000000000000..7990567f2d54f1c133e0bf7ed70bd33d64a00a7b --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/EmptyPluginOperator.java @@ -0,0 +1,88 @@ +package com.gitee.starblues.integration.operator; + +import com.gitee.starblues.core.PluginInfo; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.integration.listener.PluginInitializerListener; +import com.gitee.starblues.integration.operator.upload.UploadParam; + +import java.nio.file.Path; +import java.util.List; + +/** + * 空操作的 PluginOperator + * + * @author starBlues + * @version 3.1.0 + * @since 3.0.4 + */ +public class EmptyPluginOperator implements PluginOperator{ + @Override + public boolean initPlugins(PluginInitializerListener pluginInitializerListener) throws PluginException { + return false; + } + + @Override + public boolean verify(Path pluginPath) throws PluginException { + return false; + } + + @Override + public PluginInfo parse(Path pluginPath) throws PluginException { + return null; + } + + @Override + public PluginInfo install(Path pluginPath, boolean unpackPlugin) throws PluginException { + return null; + } + + @Override + public void uninstall(String pluginId, boolean isDelete, boolean isBackup) throws PluginException { + + } + + @Override + public PluginInfo load(Path pluginPath, boolean unpackPlugin) throws PluginException { + return null; + } + + @Override + public boolean unload(String pluginId) throws PluginException { + return false; + } + + @Override + public boolean start(String pluginId) throws PluginException { + return false; + } + + @Override + public boolean stop(String pluginId) throws PluginException { + return false; + } + + @Override + public PluginInfo uploadPlugin(UploadParam uploadParam) throws PluginException { + return null; + } + + @Override + public Path backupPlugin(Path backDirPath, String sign) throws PluginException { + return null; + } + + @Override + public Path backupPlugin(String pluginId, String sign) throws PluginException { + return null; + } + + @Override + public List getPluginInfo() { + return null; + } + + @Override + public PluginInfo getPluginInfo(String pluginId) { + return null; + } +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java index aaf90076494cbb1ff23b230e1d2b3a15b1f5099a..c96554b47d626b5a8d31f6cadd3fc9c4bdd7dc05 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/PluginOperatorWrapper.java @@ -31,7 +31,8 @@ import java.util.List; /** * 插件操作包装者 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public class PluginOperatorWrapper implements PluginOperator{ @@ -99,7 +100,7 @@ public class PluginOperatorWrapper implements PluginOperator{ if(isDisable()){ return null; } - return pluginOperator.install(pluginPath, unpackPlugin); + return pluginOperator.load(pluginPath, unpackPlugin); } @Override diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContext.java b/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContext.java index 905623503ab6497ca1ae96710ca323744f3b6b30..af30214e2908262d5a889b97bdb0d76e0f62d960 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContext.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContext.java @@ -19,7 +19,8 @@ package com.gitee.starblues.spring; /** * 自定义ApplicationContext * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public interface ApplicationContext extends AutoCloseable { @@ -29,4 +30,10 @@ public interface ApplicationContext extends AutoCloseable { */ SpringBeanFactory getSpringBeanFactory(); + /** + * 得到原始的BeanFactory + * @return BeanFactory + */ + Object getSourceBeanFactory(); + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContextProxy.java b/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContextProxy.java index 706c7a957f1d2e3f019918905dc88652e5901b02..88e6ea5c5940e616c8557996727e317fb3f3a559 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContextProxy.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/ApplicationContextProxy.java @@ -32,6 +32,7 @@ public class ApplicationContextProxy extends GenericApplicationContext{ public ApplicationContextProxy(Object targetBeanFactory) { super(); setSpringBeanFactory(createSpringBeanFactory(targetBeanFactory)); + setSourcesBeanFactory(targetBeanFactory); } protected SpringBeanFactory createSpringBeanFactory(Object targetBeanFactory){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/GenericApplicationContext.java b/spring-brick/src/main/java/com/gitee/starblues/spring/GenericApplicationContext.java index 922899c5d4c43149b232af914896624656542b10..71590fa1283666f8d0c175262fa9ff517f3f90ba 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/GenericApplicationContext.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/GenericApplicationContext.java @@ -28,6 +28,7 @@ public class GenericApplicationContext implements ApplicationContext{ public final AutoCloseable autoCloseable; protected SpringBeanFactory springBeanFactory; + protected Object sourcesBeanFactory; public GenericApplicationContext() { this(null); @@ -41,11 +42,21 @@ public class GenericApplicationContext implements ApplicationContext{ this.springBeanFactory = Assert.isNotNull(springBeanFactory, "参数 springBeanFactory 不能为空"); } + public void setSourcesBeanFactory(Object sourcesBeanFactory) { + this.sourcesBeanFactory = sourcesBeanFactory; + } + @Override public SpringBeanFactory getSpringBeanFactory() { return springBeanFactory; } + @Override + public Object getSourceBeanFactory() { + return sourcesBeanFactory; + } + + @Override public void close() throws Exception { if(autoCloseable != null){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java index b143ef55b6387454eabb5e143d605dacd86eddb5..b6d6dec7441d4ef5a58f0635261580edbb344531 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java @@ -19,6 +19,7 @@ package com.gitee.starblues.spring; import com.gitee.starblues.spring.environment.EnvironmentProvider; import java.util.Map; +import java.util.Objects; /** * 主程序 ApplicationContext 接口 @@ -57,5 +58,10 @@ public interface MainApplicationContext extends ApplicationContext { */ boolean isWebEnvironment(); + /** + * 得到原始的 ApplicationContext + * @return Object + */ + Object getSourceApplicationContext(); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java index 4c5b61bb2845a310b424f0dab2bd7f4d03690ec1..f876ffece57eb64796cfb6b325e24f45f4f884f8 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java @@ -95,6 +95,16 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme return isWebEnvironment; } + @Override + public Object getSourceApplicationContext() { + return applicationContext; + } + + @Override + public Object getSourceBeanFactory() { + return applicationContext.getBeanFactory(); + } + private boolean getIsWebEnvironment(GenericApplicationContext applicationContext){ return applicationContext instanceof AnnotationConfigServletWebServerApplicationContext || applicationContext instanceof AnnotationConfigReactiveWebServerApplicationContext; diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/SpringPluginHook.java b/spring-brick/src/main/java/com/gitee/starblues/spring/SpringPluginHook.java index 55cdc24cf133ee55f0f4fc3dfe5b96c066177b86..54a121df0a5fb8439b6e6a676ae504e9e2bf0985 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/SpringPluginHook.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/SpringPluginHook.java @@ -17,15 +17,17 @@ package com.gitee.starblues.spring; +import com.gitee.starblues.core.PluginCloseType; import com.gitee.starblues.core.exception.PluginProhibitStopException; import com.gitee.starblues.spring.web.thymeleaf.ThymeleafConfig; /** * 插件把柄接口 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ -public interface SpringPluginHook extends AutoCloseable{ +public interface SpringPluginHook { /** * 停止前校验. 如果抛出 PluginProhibitStopException 异常, 表示当前插件不可停止 @@ -51,4 +53,12 @@ public interface SpringPluginHook extends AutoCloseable{ */ ThymeleafConfig getThymeleafConfig(); + /** + * 关闭调用 + * @param closeType 关闭类型 + * @since 3.1.0 + * @throws Exception 关闭异常 + */ + void close(PluginCloseType closeType) throws Exception; + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/extract/DefaultOpExtractFactory.java b/spring-brick/src/main/java/com/gitee/starblues/spring/extract/DefaultOpExtractFactory.java index 48b05fc06481a60d777efd7c4b6d75958a29e60e..73096b2efb8095f2253046cb674d08978dea14ea 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/extract/DefaultOpExtractFactory.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/extract/DefaultOpExtractFactory.java @@ -28,7 +28,8 @@ import java.util.stream.Collectors; /** * 默认的可扩展的工厂 * @author starBlues - * @version 3.0.0 + * @version 3.1.0 + * @since 3.0.0 */ public class DefaultOpExtractFactory implements OpExtractFactory { @@ -93,11 +94,12 @@ public class DefaultOpExtractFactory implements OpExtractFactory { if(extractCoordinates == null){ throw new RuntimeException("Not found " + coordinate + " from plugin '" + pluginId + "'"); } - Object extracts = extractCoordinates.get(coordinate); + ExtractWrapper extracts = extractCoordinates.get(coordinate); if(extracts == null){ throw new RuntimeException("Not found " + coordinate + " from plugin '" + pluginId + "'"); } - return (T) extracts; + // fix https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I5IFR4 + return (T) extracts.getObject(); } @SuppressWarnings("unchecked") diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/web/PluginStaticResourceResolver.java b/spring-brick/src/main/java/com/gitee/starblues/spring/web/PluginStaticResourceResolver.java index 3a2d192d20ef505ed637d20932f6d4839892c66e..09232f34992a652bd63a0fb90586a5d6b5fe753f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/web/PluginStaticResourceResolver.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/web/PluginStaticResourceResolver.java @@ -252,7 +252,7 @@ public class PluginStaticResourceResolver extends AbstractResourceResolver { public static synchronized void parse(PluginDescriptor pluginDescriptor, ClassLoader pluginClassLoader, WebConfig webConfig){ - if(!webConfig.isEnable()){ + if(webConfig == null || !webConfig.isEnable()){ return; } final Set locations = webConfig.getResourceLocations(); diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/web/thymeleaf/PluginThymeleafInvolved.java b/spring-brick/src/main/java/com/gitee/starblues/spring/web/thymeleaf/PluginThymeleafInvolved.java index 999816eb97da94b155342fea1cbcd4267fdf2688..333f0afc32f9ef5ef10763dc1bea74b93b2ffaa0 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/web/thymeleaf/PluginThymeleafInvolved.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/web/thymeleaf/PluginThymeleafInvolved.java @@ -16,6 +16,7 @@ package com.gitee.starblues.spring.web.thymeleaf; +import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; import com.gitee.starblues.integration.IntegrationConfiguration; @@ -36,7 +37,8 @@ import java.util.concurrent.ConcurrentHashMap; /** * 插件 Thymeleaf 注册 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public class PluginThymeleafInvolved implements PluginLaunchInvolved { @@ -52,7 +54,7 @@ public class PluginThymeleafInvolved implements PluginLaunchInvolved { } @Override - public void after(InsidePluginDescriptor descriptor, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { + public void after(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader, SpringPluginHook pluginHook) throws Exception { if(templateResolvers == null){ return; } @@ -93,14 +95,15 @@ public class PluginThymeleafInvolved implements PluginLaunchInvolved { } resolver.setCheckExistence(true); templateResolvers.add(resolver); + InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); if(!pluginTemplateResolver.containsKey(descriptor.getPluginId())){ pluginTemplateResolver.put(descriptor.getPluginId(), resolver); } } @Override - public void close(InsidePluginDescriptor descriptor, ClassLoader classLoader) throws Exception { - pluginTemplateResolver.remove(descriptor.getPluginId()); + public void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { + pluginTemplateResolver.remove(pluginInsideInfo.getPluginId()); } private SpringTemplateEngine getSpringTemplateEngine(GenericApplicationContext context){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/utils/PluginFileUtils.java b/spring-brick/src/main/java/com/gitee/starblues/utils/PluginFileUtils.java index 3e1423ea39e138dc36856d073b0fddb70ff2794d..fb01b0d94854edc0c23520f51455b7f13398b486 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/utils/PluginFileUtils.java +++ b/spring-brick/src/main/java/com/gitee/starblues/utils/PluginFileUtils.java @@ -17,7 +17,9 @@ package com.gitee.starblues.utils; +import com.gitee.starblues.common.ManifestKey; import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.common.PackageType; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -32,6 +34,7 @@ import java.nio.file.Paths; import java.security.MessageDigest; import java.util.Enumeration; import java.util.List; +import java.util.Objects; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.zip.ZipEntry; @@ -41,7 +44,8 @@ import java.util.zip.ZipFile; * 插件文件工具类 * * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.1.0 */ public final class PluginFileUtils { @@ -187,7 +191,9 @@ public final class PluginFileUtils { } File targetDirFile = new File(targetDir); if(!targetDirFile.exists()){ - targetDirFile.mkdirs(); + if(!targetDirFile.mkdirs()){ + throw new IOException("创建目录异常: " + targetDir); + } } try (ZipFile zip = new ZipFile(zipFile, Charset.forName(PackageStructure.CHARSET_NAME))) { Enumeration zipEnumeration = zip.entries(); @@ -201,23 +207,34 @@ public final class PluginFileUtils { if (zipEntry.isDirectory()) { FileUtils.forceMkdir(new File(currentTargetPath)); continue; + } else { + FilesUtils.createFile(currentTargetPath); } - InputStream in = null; - FileOutputStream out = null; - try { - in = zip.getInputStream(zipEntry); - out = new FileOutputStream(currentTargetPath); - IOUtils.copy(in, out); - } finally { - if (in != null) { - IOUtils.closeQuietly(in); - } - if (out != null) { - IOUtils.closeQuietly(out); + try (InputStream in = zip.getInputStream(zipEntry); + FileOutputStream out = new FileOutputStream(currentTargetPath)){ + if(PackageStructure.PROD_MANIFEST_PATH.equals(zipEntryName)){ + // 如果为 Manifest 文件, 则将打包类型切换为 xx-outer + resolveDecompressPluginType(in, out); + } else { + IOUtils.copy(in, out); } } } } } + + private static void resolveDecompressPluginType(InputStream inputStream, OutputStream outputStream) throws IOException{ + Manifest manifest = new Manifest(inputStream); + Attributes mainAttributes = manifest.getMainAttributes(); + String value = mainAttributes.getValue(ManifestKey.PLUGIN_PACKAGE_TYPE); + if(Objects.equals(value, PackageType.MAIN_PACKAGE_TYPE_JAR)){ + value = PackageType.PLUGIN_PACKAGE_TYPE_DIR; + } else if(Objects.equals(value, PackageType.PLUGIN_PACKAGE_TYPE_ZIP)){ + value = PackageType.PLUGIN_PACKAGE_TYPE_DIR; + } + mainAttributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, value); + manifest.write(outputStream); + } + } diff --git a/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java b/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginIsolationLauncherCheckerTest.java similarity index 97% rename from spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java rename to spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginIsolationLauncherCheckerTest.java index 09d895d26c40e1b33acffbee44cf4c33ec620244..559b996f3bd168b1a652b14f7d3827da6bcc6088 100644 --- a/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java +++ b/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginIsolationLauncherCheckerTest.java @@ -44,7 +44,7 @@ import static org.powermock.api.mockito.PowerMockito.*; * @version 3.0.0 */ @RunWith(PowerMockRunner.class) -public class DefaultPluginLauncherCheckerTest extends TestCase { +public class DefaultPluginIsolationLauncherCheckerTest extends TestCase { private DefaultPluginLauncherChecker launcherChecker; diff --git a/update.md b/update.md index 6bbe377578eb573664e693f3fa5193b7283d6946..6d62995f3dc1293f30549a68fbfd15590d6235dd 100644 --- a/update.md +++ b/update.md @@ -1,20 +1,14 @@ -1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 插件可触发`WebServerInitializedEvent`类型的事件 -2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) -3. 【新增】插件新增`@AutowiredType`注解, 可指定依赖注入类型 -4. 【新增】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) -5. 【新增】新增`PluginContextHolder`, 使用方式见文档: [PluginContextHolder使用说明](https://www.yuque.com/starblues/spring-brick-3.0.0/un3cic) -6. 【优化】优化静态资源文件加载问题 -7. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` -8. 【优化】优化从主程序依赖加载`Class`资源模块 -9. 【优化】优化插件中注入异常提示 -10. 【优化】优化`Swagger`相关功能 -11. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -12. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -13. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 -14. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 -15. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 -16. 【修复】修复`StopValidator`禁止插件停止时, 插件状态变为`STOPPED_FAILURE`问题 -17. 【修复】解决`jdk17`反射问题, 导致无法注册插件`Controller`问题 +1. 【新增】增加主包MAINIFEST中title和version定义, 标准jar包中包含`Implementation-Version`和`Implementation-Title`属性 +2. 【新增】新增根据个人需求选择开发模式,支持隔离式开发模式(目前已有的)、共享式开发模式 +3. 【新增】新增可自主实现扩展插件信息 +4. 【新增】新增插件停止类型 +3. 【修复】修复插件中`LiveBeansView`注册异常问题 +4. 【修复[#I5IFR4](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I5IFR3)】 `ExtractFactory#getExtractByCoordinate` 类型转换`Bug` +5. 【修复[#I5GJO9](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I5GJO9)】`DefaultPluginManager#install` 异常无法抛出 +6. 【修复】修复插件无法加载其他包依赖中的`mybatis-xml`问题 +7. 【修复】修复插件子启动问题 +8. 【修复】修复插件`load`解压异常 +9. 【修复】修复`jar`、`zip`加载依赖时未使用`libDir`配置前缀 +10.【优化】优化插件`parse`后为`parsed`状态 +11.【优化】优化依赖资源默认不缓存, 以减少内存 - -- 注意: 本次升级后, 从主程序注入的`Bean`, 需设置注入类型, 详见文档: [插件中注入主程序Bean说明](https://www.yuque.com/starblues/spring-brick-3.0.0/vot8gg) \ No newline at end of file