diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeDefinerConfig.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeDefinerConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..2481c0b13d52707841487cbd9432874bbeac31ea --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeDefinerConfig.java @@ -0,0 +1,58 @@ +/** + * 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.realize.AutowiredTypeDefiner; +import com.gitee.starblues.utils.ObjectUtils; + +import java.util.*; + +/** + * 配置 ClassDefiner + * + * @author starBlues + * @since 3.0.3 + * @version 3.0.3 + */ +public class AutowiredTypeDefinerConfig { + + private final Set classDefiners; + + public AutowiredTypeDefinerConfig(){ + this.classDefiners = new HashSet<>(); + } + + Set getClassDefiners(){ + return classDefiners; + } + + public AutowiredTypeDefinerConfig add(AutowiredType.Type type, String... classNamePatterns){ + if(type != null && classNamePatterns != null && classNamePatterns.length > 0){ + classDefiners.add(AutowiredTypeDefiner.ClassDefiner.config(type, classNamePatterns)); + } + return this; + } + + public AutowiredTypeDefinerConfig add(AutowiredType.Type type, Class... classes){ + if(type != null && classes != null && classes.length > 0){ + classDefiners.add(AutowiredTypeDefiner.ClassDefiner.config(type, classes)); + } + return this; + } + +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..cdbf3454fd4b0eb504eeccb16840c68075005ae1 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.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.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.ObjectUtils; +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; + +/** + * @author starBlues + * @since 3.0.3 + * @version 3.0.3 + */ +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; + } + } + + +} 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/ConfigureMainPluginEnvironment.java index c2e0080564535f9d08d943077d88ce6882844b22..912f2546cda5c555de6622fedaf650c596209b32 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/ConfigureMainPluginEnvironment.java @@ -39,6 +39,7 @@ import java.util.*; * 插件环境配置 * @author starBlues * @version 3.0.0 + * @since 3.0.0 */ class ConfigureMainPluginEnvironment { 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 34c6c9c6274e63a375f0c4427c74458dd381239a..7608046cae2e2f9f2d41522922e8c80dcb2d4026 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 @@ -18,6 +18,9 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; +import com.gitee.starblues.spring.environment.EmptyEnvironmentProvider; +import com.gitee.starblues.spring.environment.EnvironmentProvider; + import java.util.Collections; import java.util.Map; import java.util.Set; @@ -46,6 +49,11 @@ public class EmptyMainApplicationContext implements MainApplicationContext { return Collections.emptyMap(); } + @Override + public EnvironmentProvider getEnvironmentProvider() { + return new EmptyEnvironmentProvider(); + } + @Override public Object resolveDependency(String requestingBeanName, Class dependencyType) { return null; diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginContextHolder.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginContextHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..253c89496778d88012cf4cead27aa891c9267d5d --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginContextHolder.java @@ -0,0 +1,121 @@ +/** + * 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.processor.ProcessorContext; +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.integration.IntegrationConfiguration; +import com.gitee.starblues.spring.SpringBeanFactory; +import com.gitee.starblues.spring.environment.EnvironmentProvider; + +/** + * 提供插件上下文的工具类 + * + * @author starBlues + * @version 3.0.3 + */ +public abstract class PluginContextHolder { + + private static volatile Boolean INITIALIZED = false; + + private static ProcessorContext processorContext; + + private static ClassLoader pluginClassLoader; + private static InsidePluginDescriptor pluginDescriptor; + + private static IntegrationConfiguration configuration; + private static Boolean mainIsWebEnv; + private static SpringBeanFactory mainSpringBeanFactory; + + + private PluginContextHolder(){} + + static void initialize(ProcessorContext processorContext){ + if(INITIALIZED){ + return; + } + PluginContextHolder.processorContext = processorContext; + + PluginContextHolder.pluginClassLoader = processorContext.getClassLoader(); + PluginContextHolder.pluginDescriptor = processorContext.getPluginDescriptor(); + PluginContextHolder.configuration = processorContext.getConfiguration(); + PluginContextHolder.mainIsWebEnv = processorContext.getMainApplicationContext().isWebEnvironment(); + PluginContextHolder.mainSpringBeanFactory = processorContext.getMainBeanFactory(); + INITIALIZED = true; + } + + /** + * 获取主程序环境中配置文件内容提供者 + * @return EnvironmentProvider + */ + public static EnvironmentProvider getEnvironmentProvider(){ + check(); + return processorContext.getMainApplicationContext().getEnvironmentProvider(); + } + + /** + * 获取主程序针对本框架的配置内容 + * @return IntegrationConfiguration + */ + public static IntegrationConfiguration getConfiguration() { + check(); + return configuration; + } + + /** + * 获取主程序的 SpringBeanFactory . 通过它可获取主程序中的Bean + * @return SpringBeanFactory + */ + public static SpringBeanFactory getMainSpringBeanFactory() { + check(); + return mainSpringBeanFactory; + } + + /** + * 判断主程序是否为web环境 + * @return Boolean + */ + public static Boolean getMainIsWebEnv() { + check(); + return mainIsWebEnv; + } + + /** + * 获取插件的 classloader + * @return ClassLoader + */ + public static ClassLoader getPluginClassLoader() { + check(); + return pluginClassLoader; + } + + /** + * 获取插件信息 + * @return InsidePluginDescriptor + */ + public static InsidePluginDescriptor getPluginDescriptor() { + check(); + return pluginDescriptor; + } + + private static void check(){ + if(!INITIALIZED){ + throw new IllegalStateException("PluginContextHolder 未初始化"); + } + } + +} 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 3aef32527716603aba9d3bcba34c7cdf856d259a..f3920cceec5d38007e5ec8cd98233dfc31ca6475 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 @@ -18,6 +18,7 @@ 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.bootstrap.utils.DestroyUtils; import com.gitee.starblues.core.classloader.MainResourceMatcher; import com.gitee.starblues.core.classloader.PluginClassLoader; @@ -30,21 +31,22 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.ScopeNotActiveException; import org.springframework.lang.Nullable; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; +import java.util.stream.Collectors; import java.util.stream.Stream; /** * 插件BeanFactory实现 * @author starBlues + * @since 3.0.3 * @version 3.0.3 */ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @@ -52,11 +54,11 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { private static final Logger LOG = LoggerFactory.getLogger(PluginListableBeanFactory.class); private final MainApplicationContext applicationContext; - private final ClassLoader pluginClassLoader; + private final AutowiredTypeResolver autowiredTypeResolver; public PluginListableBeanFactory(ProcessorContext processorContext) { this.applicationContext = processorContext.getMainApplicationContext(); - this.pluginClassLoader = processorContext.getResourceLoader().getClassLoader(); + this.autowiredTypeResolver = new AutowiredTypeResolver(processorContext); } @SuppressWarnings("unchecked") @@ -65,10 +67,6 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Nullable String requestingBeanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { - if(isDisabled(descriptor)){ - // 插件被禁用的依赖Bean直接从主程序获取。 - return resolveDependencyFromMain(requestingBeanName, descriptor); - } AutowiredType.Type autowiredType = getAutowiredType(descriptor); if(autowiredType == AutowiredType.Type.MAIN){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); @@ -80,13 +78,14 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ try { - Object object = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + Object dependencyObj = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); - if(object instanceof ObjectProvider){ - return new PluginObjectProviderWrapper((ObjectProvider) object, requestingBeanName, descriptor); + if(dependencyObj instanceof ObjectProvider){ + ObjectProvider provider = (ObjectProvider) dependencyObj; + return new PluginObjectProviderWrapper(provider, requestingBeanName, descriptor, autowiredType); } - return object; + return dependencyObj; } catch (BeansException e){ if(e instanceof NoSuchBeanDefinitionException){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); @@ -98,6 +97,10 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { } } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj instanceof ObjectProvider){ + ObjectProvider provider = (ObjectProvider) dependencyObj; + return new PluginObjectProviderWrapper(provider, requestingBeanName, descriptor, autowiredType); + } if(dependencyObj != null){ return dependencyObj; } @@ -122,29 +125,15 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { return super.getBeanProvider(requiredType, allowEagerInit); } - private AutowiredType.Type getAutowiredType(DependencyDescriptor descriptor){ - AutowiredType autowiredType = descriptor.getAnnotation(AutowiredType.class); - if(autowiredType != null){ - return autowiredType.value(); - } else { - return AutowiredType.Type.PLUGIN_MAIN; - } + protected AutowiredType.Type getAutowiredType(DependencyDescriptor descriptor){ + return autowiredTypeResolver.resolve(descriptor); } - private Object resolveDependencyFromMain(String requestingBeanName, DependencyDescriptor descriptor){ + protected Object resolveDependencyFromMain(String requestingBeanName, DependencyDescriptor descriptor){ Object dependencyObj = null; try { - if(pluginClassLoader instanceof PluginClassLoader){ - PluginClassLoader classLoader = (PluginClassLoader) pluginClassLoader; - MainResourceMatcher mainResourceMatcher = classLoader.getMainResourceMatcher(); - String className = descriptor.getDependencyType().getName(); - if(mainResourceMatcher.match(className)){ - dependencyObj = applicationContext.resolveDependency(requestingBeanName, - descriptor.getDependencyType()); - } - } else { - LOG.warn("Cannot get Bean from main program, plugin classLoader is not PluginClassLoader"); - } + dependencyObj = applicationContext.resolveDependency(requestingBeanName, + descriptor.getDependencyType()); } catch (Exception e){ return null; } @@ -164,10 +153,6 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { }); } - private boolean isDisabled(DependencyDescriptor descriptor){ - String className = descriptor.getDependencyType().getName(); - return PluginDisableAutoConfiguration.isDisabled(className); - } @AllArgsConstructor private class PluginObjectProviderWrapper implements ObjectProvider { @@ -176,114 +161,144 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { private final String requestingBeanName; private final DependencyDescriptor descriptor; + private final AutowiredType.Type autowiredType; @Override public Object getObject() throws BeansException { - if(isDisabled(descriptor)){ - return resolveDependencyFromMain(requestingBeanName, descriptor); + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getObject(); + } else { + try { + return pluginObjectProvider.getObject(); + } catch (Exception e){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + throw e; + } } - return pluginObjectProvider.getObject(); } @Override public Object getObject(final Object... args) throws BeansException { - if(isDisabled(descriptor)){ - SpringBeanFactory springBeanFactory = applicationContext.getSpringBeanFactory(); - return springBeanFactory.getBean(descriptor.getDependencyType(), args); + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getObject(args); + } else { + try { + return pluginObjectProvider.getObject(); + } catch (Exception e){ + try { + return applicationContext.getSpringBeanFactory().getBean(requestingBeanName, args); + } catch (Exception e2){ + // 忽略 + } + throw e; + } } - return pluginObjectProvider.getObject(args); } @Override @Nullable public Object getIfAvailable() throws BeansException { - if(isDisabled(descriptor)){ - try { - return getObject(); - } catch (Exception e){ - return null; + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; } - } else { return pluginObjectProvider.getIfAvailable(); + } else { + Object dependencyObj = pluginObjectProvider.getIfAvailable(); + if(dependencyObj == null){ + dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + } + return dependencyObj; } } @Override public void ifAvailable(Consumer dependencyConsumer) throws BeansException { - if(isDisabled(descriptor)){ - Object dependency = getIfAvailable(); - if (dependency != null) { - try { - dependencyConsumer.accept(dependency); - } - catch (ScopeNotActiveException ex) { - // Ignore - } - } - } else { - pluginObjectProvider.ifAvailable(dependencyConsumer); + Object ifAvailable = getIfAvailable(); + if(ifAvailable != null){ + dependencyConsumer.accept(ifAvailable); } } @Override @Nullable public Object getIfUnique() throws BeansException { - if(isDisabled(descriptor)){ - Object dependency = getIfAvailable(); - if(dependency == null){ - return Optional.empty(); - } else { - return Optional.of(dependency); + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; } - } else { return pluginObjectProvider.getIfUnique(); + } else { + Object dependencyObj = pluginObjectProvider.getIfUnique(); + if(dependencyObj == null){ + dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + } + return dependencyObj; } } @Override public void ifUnique(Consumer dependencyConsumer) throws BeansException { - if(isDisabled(descriptor)){ - Object dependency = getIfUnique(); - if (dependency != null) { - try { - dependencyConsumer.accept(dependency); - } catch (ScopeNotActiveException ex) { - // Ignore - } - } - } else { - pluginObjectProvider.ifUnique(dependencyConsumer); + Object ifUnique = getIfUnique(); + if(ifUnique != null){ + dependencyConsumer.accept(ifUnique); } } @Override public Stream stream() { - if(isDisabled(descriptor)){ - return getStreamOfMain(); - } else { + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Set collection = getStreamOfMain(); + if(!collection.isEmpty()){ + return collection.stream(); + } return pluginObjectProvider.stream(); + } else { + Stream stream = pluginObjectProvider.stream(); + List collect = stream.collect(Collectors.toList()); + if(!collect.isEmpty()){ + return collect.stream(); + } + return getStreamOfMain().stream(); } } @Override public Stream orderedStream() { - if(isDisabled(descriptor)){ - // TODO 随意排序 - return getStreamOfMain().sorted(); + if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Set collection = getStreamOfMain(); + if(!collection.isEmpty()){ + return collection.stream().sorted(); + } + return pluginObjectProvider.stream(); } else { - return pluginObjectProvider.orderedStream(); + Stream stream = pluginObjectProvider.stream(); + List collect = stream.collect(Collectors.toList()); + if(!collect.isEmpty()){ + return collect.stream(); + } + return getStreamOfMain().stream().sorted(); } } @SuppressWarnings("unchecked") - private Stream getStreamOfMain(){ + private Set getStreamOfMain(){ SpringBeanFactory springBeanFactory = applicationContext.getSpringBeanFactory(); Map beansOfType = springBeanFactory.getBeansOfType(descriptor.getDependencyType()); - if(beansOfType.isEmpty()){ - return Stream.empty(); - } else { - return (Stream) beansOfType.values().stream(); - } + return new HashSet<>(beansOfType.values()); } } 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 abdb79f83e346e8dd4d45fdc615deb159d8e974c..d923a1b0399f207ec8a7519fd8ea587c46dab0d2 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 @@ -102,6 +102,7 @@ public class PluginSpringApplication extends SpringApplication { public ConfigurableApplicationContext run(String... args) { try { processorContext.setApplicationContext(this.applicationContext); + PluginContextHolder.initialize(processorContext); pluginProcessor.initialize(processorContext); return super.run(args); } catch (Exception e) { diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java index 64bb67f4ea03e684e88fcb068bb2c4c6f6431067..9539cb34c409ed7d05c6821a774d89946d98d194 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java @@ -18,8 +18,7 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.bootstrap.listener.PluginApplicationWebEventListener; import com.gitee.starblues.bootstrap.processor.ProcessorContext; -import com.gitee.starblues.bootstrap.realize.DefaultMainEnvironmentProvider; -import com.gitee.starblues.bootstrap.realize.MainEnvironmentProvider; +import com.gitee.starblues.spring.environment.EnvironmentProvider; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; @@ -38,9 +37,7 @@ public class PluginWebApplicationContext extends PluginApplicationContext implem public PluginWebApplicationContext(DefaultListableBeanFactory beanFactory, ProcessorContext processorContext) { super(beanFactory, processorContext); - MainEnvironmentProvider environmentProvider = new DefaultMainEnvironmentProvider( - processorContext.getMainApplicationContext()); - this.webServer = new PluginSimulationWebServer(environmentProvider); + this.webServer = new PluginSimulationWebServer(processorContext); this.serverNamespace = processorContext.getPluginDescriptor().getPluginId(); addApplicationListener(new PluginApplicationWebEventListener(this)); } @@ -60,8 +57,9 @@ public class PluginWebApplicationContext extends PluginApplicationContext implem private final int port; - public PluginSimulationWebServer(MainEnvironmentProvider environmentProvider) { - Integer port = environmentProvider.getInteger("server.port"); + public PluginSimulationWebServer(ProcessorContext processorContext) { + EnvironmentProvider provider = processorContext.getMainApplicationContext().getEnvironmentProvider(); + Integer port = provider.getInteger("server.port"); if(port == null){ this.port = -1; } else { 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 b54de8b32a9287fa8f8fda930b130ff5e066d585..14d882af9c0bc7a1e033835b6b2548e3b3838a89 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 @@ -20,6 +20,7 @@ import com.gitee.starblues.bootstrap.processor.ComposeSpringPluginProcessor; 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.bootstrap.realize.AutowiredTypeDefiner; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; import com.gitee.starblues.spring.SpringPluginHook; @@ -29,7 +30,8 @@ import java.util.List; /** * 插件引导抽象类。插件入口需集成本抽象类 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public abstract class SpringPluginBootstrap { @@ -96,4 +98,14 @@ public abstract class SpringPluginBootstrap { */ protected void addCustomSpringPluginProcessor(){} + /** + * 设置 AutowiredTypeDefiner + * @return AutowiredTypeDefiner + * @since 3.0.3 + */ + protected AutowiredTypeDefiner autowiredTypeDefiner(){ + return null; + } + + } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java index af34b0084a66b9d03b89df496d3167a6d73ceb47..1d9d583747e0a54d9936edecd2a1e43f8d56832f 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java @@ -18,28 +18,29 @@ public @interface AutowiredType { * 插件Bean注入类型 * @return Type */ - Type value() default Type.PLUGIN_MAIN; + Type value() default Type.PLUGIN; + enum Type{ /** - * Bean 注入类型(默认): 先插件后主程序 + * Bean 注入类型: 仅插件(默认) */ - PLUGIN_MAIN, + PLUGIN, /** - * Bean 注入类型: 先主程序后插件 + * Bean 注入类型: 仅主程序 */ - MAIN_PLUGIN, + MAIN, /** - * Bean 注入类型: 仅插件 + * Bean 注入类型: 先插件后主程序 */ - PLUGIN, + PLUGIN_MAIN, /** - * Bean 注入类型: 仅主程序 + * Bean 注入类型: 先主程序后插件 */ - MAIN + MAIN_PLUGIN } 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 d9d85e090eb25c0a030e640999f5ca7725d55996..d0801cc961327e0ac7d1c5ca04f81a5a9cce6375 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 @@ -25,10 +25,14 @@ import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.spring.WebConfig; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; +import java.util.Map; + /** * 默认的处理者上下文 * @author starBlues @@ -131,8 +135,8 @@ public class DefaultProcessorContext extends CacheRegistryInfo implements Proces this.applicationContext = applicationContext; } - protected ClassLoader getPluginClassLoader(){ return ClassUtils.getDefaultClassLoader(); } + } 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 56fcb6af01916a9de51eaf1c8c57d56230c3229a..ddbb7b8fafdb53c4fff23c623e33252e9fe665e9 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 @@ -17,9 +17,6 @@ package com.gitee.starblues.bootstrap.processor; -import com.gitee.starblues.bootstrap.realize.DefaultMainEnvironmentProvider; -import com.gitee.starblues.bootstrap.realize.EmptyMainEnvironmentProvider; -import com.gitee.starblues.bootstrap.realize.MainEnvironmentProvider; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.integration.AutoIntegrationConfiguration; import com.gitee.starblues.integration.ExtendPointConfiguration; @@ -40,16 +37,6 @@ public class FrameDefineBeanProcessor implements SpringPluginProcessor { ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory(); beanFactory.registerSingleton("pluginDescriptor", pluginDescriptor.toPluginDescriptor()); beanFactory.registerSingleton("mainApplicationContext", context.getMainApplicationContext()); - - MainEnvironmentProvider mainEnvironmentProvider = null; - if(context.runMode() == ProcessorContext.RunMode.ONESELF){ - beanFactory.registerSingleton("integrationConfiguration", new AutoIntegrationConfiguration()); - applicationContext.registerBean(ExtendPointConfiguration.class); - mainEnvironmentProvider = new EmptyMainEnvironmentProvider(); - } else { - mainEnvironmentProvider = new DefaultMainEnvironmentProvider(context.getMainApplicationContext()); - } - beanFactory.registerSingleton("mainEnvironmentProvider", mainEnvironmentProvider); } @Override 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 db4c125427aa79507918a11895fa75cf05606bd0..42cec5b55f5ed4a9e55a0ae6f1f09e1cf8140d77 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 @@ -26,6 +26,7 @@ import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.spring.WebConfig; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.io.ResourceLoader; /** 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 a23b314936228bd4c6e4b15e54797f2e3ba21c47..3840ab5a18aa3ac08b84ff2b4bfbabe2ac7f4f87 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 @@ -32,16 +32,20 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; /** * 插件Controller处理者 @@ -77,8 +81,8 @@ public class PluginControllerProcessor implements SpringPluginProcessor { return; } GenericApplicationContext applicationContext = processorContext.getApplicationContext(); - applicationContext.registerBean("changeRestPathPostProcessor", - ChangeRestPathPostProcessor.class, ()-> new ChangeRestPathPostProcessor(processorContext)); + applicationContext.registerBean("pluginControllerPostProcessor", + ControllerPostProcessor.class, ()-> new ControllerPostProcessor(processorContext)); } @Override @@ -94,9 +98,8 @@ public class PluginControllerProcessor implements SpringPluginProcessor { GenericApplicationContext applicationContext = processorContext.getApplicationContext(); Iterator iterator = controllerWrappers.iterator(); - - PluginRequestMappingHandlerMapping pluginHandlerMapping = new PluginRequestMappingHandlerMapping(); - + String pathPrefix = PluginConfigUtils.getPluginRestPrefix(processorContext.getConfiguration(), pluginId); + PluginRequestMappingHandlerMapping pluginHandlerMapping = new PluginRequestMappingHandlerMapping(pathPrefix); while (iterator.hasNext()){ ControllerWrapper controllerWrapper = iterator.next(); @@ -158,14 +161,13 @@ public class PluginControllerProcessor implements SpringPluginProcessor { } } - private static class ChangeRestPathPostProcessor implements BeanPostProcessor { + private static class ControllerPostProcessor implements BeanPostProcessor { - private final static Logger LOG = LoggerFactory.getLogger(ChangeRestPathPostProcessor.class); - private final static String COMMON_ERROR = "无法统一处理该Controller请求路径前缀"; + private final static Logger LOG = LoggerFactory.getLogger(ControllerPostProcessor.class); private final ProcessorContext processorContext; - private ChangeRestPathPostProcessor(ProcessorContext processorContext) { + private ControllerPostProcessor(ProcessorContext processorContext) { this.processorContext = processorContext; } @@ -178,62 +180,21 @@ public class PluginControllerProcessor implements SpringPluginProcessor { Controller.class, RestController.class }); if(requestMapping != null && isController){ - changePathForClass(beanName, aClass, requestMapping); + addControllerWrapper(beanName, aClass); } return bean; } - private void changePathForClass(String beanName, Class aClass, RequestMapping requestMapping){ - String pluginId = processorContext.getPluginDescriptor().getPluginId(); - IntegrationConfiguration configuration = processorContext.getConfiguration(); - String pathPrefix = PluginConfigUtils.getPluginRestPrefix(configuration, pluginId); - try { - if(!ObjectUtils.isEmpty(pathPrefix)){ - resolvePathPrefix(pathPrefix, aClass, requestMapping); - } - List controllerWrappers = processorContext.getRegistryInfo(PROCESS_CONTROLLERS); - if(controllerWrappers == null){ - controllerWrappers = new ArrayList<>(); - processorContext.addRegistryInfo(PROCESS_CONTROLLERS, controllerWrappers); - } - ControllerWrapper controllerWrapper = new ControllerWrapper(); - controllerWrapper.setBeanName(beanName); - controllerWrapper.setBeanClass(aClass); - controllerWrappers.add(controllerWrapper); - } catch (Exception e) { - LOG.error("插件 [{}] Controller 类[{}] 注册异常. {}", pluginId, aClass.getName(), e.getMessage(), e); - } - } - - private void resolvePathPrefix(String pathPrefix, Class aClass, RequestMapping requestMapping) throws Exception{ - String pluginId = processorContext.getPluginDescriptor().getPluginId(); - - Map memberValues = ClassUtils.getAnnotationsUpdater(requestMapping); - if(memberValues == null){ - LOG.error("插件 [{}] Controller 类 [{}] 无法反射获取注解属性, {}", - pluginId, aClass.getSimpleName(), COMMON_ERROR); - return; - } - - Set definePaths = new HashSet<>(); - definePaths.addAll(Arrays.asList(requestMapping.path())); - definePaths.addAll(Arrays.asList(requestMapping.value())); - - String[] newPath = new String[definePaths.size()]; - int i = 0; - for (String definePath : definePaths) { - // 解决插件启用、禁用后, 路径前缀重复的问题。 - if(definePath.contains(pathPrefix)){ - newPath[i++] = definePath; - } else { - newPath[i++] = UrlUtils.restJoiningPath(pathPrefix, definePath); - } - } - if(newPath.length == 0){ - newPath = new String[]{ pathPrefix }; + private void addControllerWrapper(String beanName, Class aClass){ + List controllerWrappers = processorContext.getRegistryInfo(PROCESS_CONTROLLERS); + if(controllerWrappers == null){ + controllerWrappers = new ArrayList<>(); + processorContext.addRegistryInfo(PROCESS_CONTROLLERS, controllerWrappers); } - memberValues.put("path", newPath); - memberValues.put("value", newPath); + ControllerWrapper controllerWrapper = new ControllerWrapper(); + controllerWrapper.setBeanName(beanName); + controllerWrapper.setBeanClass(aClass); + controllerWrappers.add(controllerWrapper); } } @@ -262,6 +223,18 @@ public class PluginControllerProcessor implements SpringPluginProcessor { private final List registerMappingInfo = new ArrayList<>(); + public PluginRequestMappingHandlerMapping(){ + this(null); + } + + public PluginRequestMappingHandlerMapping(String pathPrefix){ + if(!ObjectUtils.isEmpty(pathPrefix)){ + Map>> prefixes = new HashMap<>(); + prefixes.put(pathPrefix, c->true); + setPathPrefixes(prefixes); + } + } + public void registerHandler(Object handler){ detectHandlerMethods(handler); } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/AutowiredTypeDefiner.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/AutowiredTypeDefiner.java new file mode 100644 index 0000000000000000000000000000000000000000..a81d519d1c3ebc35aee7cf8eb08fa7a6f295908c --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/AutowiredTypeDefiner.java @@ -0,0 +1,95 @@ +/** + * 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.realize; + +import com.gitee.starblues.bootstrap.AutowiredTypeDefinerConfig; +import com.gitee.starblues.bootstrap.annotation.AutowiredType; +import com.gitee.starblues.utils.UrlUtils; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.HashSet; +import java.util.Set; + +/** + * autowiredType 批量定义接口 + * + * @author starBlues + * @since 3.0.3 + * @version 3.0.3 + */ +public interface AutowiredTypeDefiner { + + /** + * 定义 ClassDefiner + * @param config 往config中进行配置 ClassDefiner + */ + void config(AutowiredTypeDefinerConfig config); + + + @Getter + @EqualsAndHashCode + class ClassDefiner{ + /** + * 注入类型 + */ + private final AutowiredType.Type autowiredType; + + /** + * 类名称匹配 + */ + private final Set classNamePatterns; + + private ClassDefiner(AutowiredType.Type autowiredType, Set classNamePatterns){ + this.autowiredType = autowiredType; + this.classNamePatterns = classNamePatterns; + } + + public static ClassDefiner config(AutowiredType.Type autowiredType, Class... classes){ + if(autowiredType == null){ + throw new IllegalArgumentException("autowiredType 参数不能为空"); + } + int length = classes.length; + if(length == 0){ + throw new IllegalArgumentException("classes 参数不能为空"); + } + Set classNamePatterns = new HashSet<>(length); + for (Class aClass : classes) { + classNamePatterns.add(UrlUtils.formatMatchUrl(aClass.getName())); + } + return new ClassDefiner(autowiredType, classNamePatterns); + } + + public static ClassDefiner config(AutowiredType.Type autowiredType, String... classNamePatterns){ + if(autowiredType == null){ + throw new IllegalArgumentException("autowiredType 参数不能为空"); + } + int length = classNamePatterns.length; + if(length == 0){ + throw new IllegalArgumentException("classNamePatterns 参数不能为空"); + } + Set classNamePatternsSet = new HashSet<>(length); + for (String classNamePattern : classNamePatterns) { + classNamePatternsSet.add(UrlUtils.formatMatchUrl(classNamePattern)); + } + return new ClassDefiner(autowiredType, classNamePatternsSet); + } + + } + + +} 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 dfdfd66132e1526abcd3d4048c2db539bccb9b5f..7942eae37c9c9f42b603a55986275809fabe734f 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 @@ -21,6 +21,7 @@ import com.gitee.starblues.core.descriptor.PluginDescriptor; /** * 插件被停止监听者。用于自定义关闭资源 * @author starBlues + * @since 3.0.0 * @version 3.0.0 */ public interface PluginCloseListener { diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/StopValidator.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/StopValidator.java index be1d74dbc0046d706f3630287e366d653c820366..54e58a0c927eef7fb39c09043dbd3dd9a0c366f6 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/StopValidator.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/StopValidator.java @@ -19,7 +19,8 @@ package com.gitee.starblues.bootstrap.realize; /** * 插件停止校验器. 自主实现判断是否可卸载 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public interface StopValidator { @@ -27,6 +28,7 @@ public interface StopValidator { /** * 校验是否可停止/卸载。如果校验器抛出异常. 默认插件不可停止/卸载 * @return 校验结果 + * @since 3.0.0 */ Result verify(); @@ -52,6 +54,34 @@ public interface StopValidator { this.message = message; } + /** + * 可卸载 + * @return Result + * @since 3.0.3 + */ + public static Result ok(){ + return new Result(true); + } + + /** + * 禁止停止 + * @return Result + * @since 3.0.3 + */ + public static Result forbid(){ + return forbid(null); + } + + /** + * 禁止停止 + * @param message 禁止停止信息 + * @return Result + * @since 3.0.3 + */ + public static Result forbid(String message){ + return new Result(false, message); + } + public boolean isVerify() { return verify; } diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java index 191198e03a3c660833f162307f0c72950b610e26..813844c0f545a7f876e789298e61f2abb813921f 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java @@ -8,27 +8,31 @@ import java.util.function.Function; * map 值获取者工具类 * * @author starBlues - * @version 3.0.1 + * @version 3.0.3 */ public class MapValueGetter { - private final Map map; + private final Map source; - public MapValueGetter(Map map) { - if(map == null){ - this.map = Collections.emptyMap(); + public MapValueGetter(Map source) { + if(source == null){ + this.source = Collections.emptyMap(); } else { - this.map = map; + this.source = source; } } + public Map getSource(){ + return source; + } + /** * 获取object * @param key map key * @return value */ public Object getObject(String key) { - return map.get(key); + return source.get(key); } @@ -38,7 +42,7 @@ public class MapValueGetter { * @return String value */ public String getString(String key) { - return getValue(key, String::valueOf); + return getValue(key, ObjectValueUtils::getString); } /** @@ -47,12 +51,7 @@ public class MapValueGetter { * @return Integer value */ public Integer getInteger(String key) { - return getValue(key, value -> { - if(value instanceof Integer){ - return (Integer) value; - } - return Integer.parseInt(String.valueOf(value)); - }); + return getValue(key, ObjectValueUtils::getInteger); } /** @@ -61,12 +60,7 @@ public class MapValueGetter { * @return Long value */ public Long getLong(String key) { - return getValue(key, value -> { - if(value instanceof Long){ - return (Long) value; - } - return Long.parseLong(String.valueOf(value)); - }); + return getValue(key, ObjectValueUtils::getLong); } /** @@ -75,12 +69,7 @@ public class MapValueGetter { * @return Double value */ public Double getDouble(String key) { - return getValue(key, value -> { - if(value instanceof Double){ - return (Double) value; - } - return Double.parseDouble(String.valueOf(value)); - }); + return getValue(key, ObjectValueUtils::getDouble); } /** @@ -89,12 +78,7 @@ public class MapValueGetter { * @return Float value */ public Float getFloat(String key) { - return getValue(key, value -> { - if(value instanceof Float){ - return (Float) value; - } - return Float.parseFloat(String.valueOf(value)); - }); + return getValue(key, ObjectValueUtils::getFloat); } /** @@ -103,12 +87,7 @@ public class MapValueGetter { * @return Boolean value */ public Boolean getBoolean(String key) { - return getValue(key, value -> { - if(value instanceof Boolean){ - return (Boolean) value; - } - return Boolean.parseBoolean(String.valueOf(value)); - }); + return getValue(key, ObjectValueUtils::getBoolean); } /** diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectValueUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectValueUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..9f3472511754ebe47ac0d794be30f84833a4de0e --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectValueUtils.java @@ -0,0 +1,90 @@ +/** + * 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.utils; + +/** + * object value convert utils + * + * @author starBlues + * @version 3.0.3 + */ +public abstract class ObjectValueUtils { + + private ObjectValueUtils(){ + } + + public static String getString(Object value){ + if(value == null){ + return null; + } + if(value instanceof CharSequence){ + return ((CharSequence) value).toString(); + } + return String.valueOf(value); + } + + public static Integer getInteger(Object value){ + if(value == null){ + return null; + } + if(value instanceof Integer){ + return (Integer) value; + } + return Integer.parseInt(String.valueOf(value)); + } + + public static Long getLong(Object value){ + if(value == null){ + return null; + } + if(value instanceof Long){ + return (Long) value; + } + return Long.parseLong(String.valueOf(value)); + } + + public static Double getDouble(Object value) { + if(value == null){ + return null; + } + if(value instanceof Double){ + return (Double) value; + } + return Double.parseDouble(String.valueOf(value)); + } + + public static Float getFloat(Object value) { + if(value == null){ + return null; + } + if(value instanceof Float){ + return (Float) value; + } + return Float.parseFloat(String.valueOf(value)); + } + + public static Boolean getBoolean(Object value) { + if(value == null){ + return null; + } + if(value instanceof Boolean){ + return (Boolean) value; + } + return Boolean.parseBoolean(String.valueOf(value)); + } + +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/UrlUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/UrlUtils.java index 90b80dbc4dbd3a069e095ec4aca0477ee11a266a..e4c7bdd42b90cf4aa1b4637db663d5620f661112 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/utils/UrlUtils.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/UrlUtils.java @@ -20,13 +20,17 @@ package com.gitee.starblues.utils; * http url util * * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public class UrlUtils { private UrlUtils(){} - public static final String SPLIT = "/"; + public static final String PATH_SEPARATOR = "/"; + + public final static String SEPARATOR_DOT = "."; + public final static String SEPARATOR_BACKSLASH = "\\"; /** * rest接口拼接路径 @@ -34,13 +38,14 @@ public class UrlUtils { * @param path1 路径1 * @param path2 路径2 * @return 拼接的路径 + * @since 3.0.0 */ public static String restJoiningPath(String path1, String path2){ if(path1 != null && path2 != null){ - if(path1.endsWith(SPLIT) && path2.startsWith(SPLIT)){ + if(path1.endsWith(PATH_SEPARATOR) && path2.startsWith(PATH_SEPARATOR)){ return path1 + path2.substring(1); - } else if(!path1.endsWith(SPLIT) && !path2.startsWith(SPLIT)){ - return path1 + SPLIT + path2; + } else if(!path1.endsWith(PATH_SEPARATOR) && !path2.startsWith(PATH_SEPARATOR)){ + return path1 + PATH_SEPARATOR + path2; } else { return path1 + path2; } @@ -59,6 +64,7 @@ public class UrlUtils { * * @param paths 拼接的路径 * @return 拼接的路径 + * @since 3.0.0 */ public static String joiningUrlPath(String ...paths){ if(paths == null || paths.length == 0){ @@ -71,13 +77,13 @@ public class UrlUtils { if(ObjectUtils.isEmpty(path)) { continue; } - if((i < length - 1) && path.endsWith(SPLIT)){ - path = path.substring(path.lastIndexOf(SPLIT)); + if((i < length - 1) && path.endsWith(PATH_SEPARATOR)){ + path = path.substring(path.lastIndexOf(PATH_SEPARATOR)); } - if(path.startsWith(SPLIT)){ + if(path.startsWith(PATH_SEPARATOR)){ stringBuilder.append(path); } else { - stringBuilder.append(SPLIT).append(path); + stringBuilder.append(PATH_SEPARATOR).append(path); } } @@ -88,12 +94,13 @@ public class UrlUtils { * 格式化 url * @param url 原始url * @return 格式化后的url + * @since 3.0.0 */ public static String format(String url){ if(ObjectUtils.isEmpty(url)){ return url; } - String[] split = url.split(SPLIT); + String[] split = url.split(PATH_SEPARATOR); StringBuilder stringBuilder = new StringBuilder(); int length = split.length; for (int i = 0; i < length; i++) { @@ -102,7 +109,7 @@ public class UrlUtils { continue; } if(i < length - 1){ - stringBuilder.append(str).append(SPLIT); + stringBuilder.append(str).append(PATH_SEPARATOR); } else { stringBuilder.append(str); } @@ -110,4 +117,23 @@ public class UrlUtils { return stringBuilder.toString(); } + /** + * 格式化匹配url时的格式 + * @param url url + * @return 格式化后 + * @since 3.0.3 + */ + public static String formatMatchUrl(String url){ + if(url.contains(SEPARATOR_DOT)){ + url = url.replace(SEPARATOR_DOT, PATH_SEPARATOR); + } + if(url.contains(SEPARATOR_BACKSLASH)){ + url = url.replace(SEPARATOR_BACKSLASH, PATH_SEPARATOR); + } + if(url.startsWith(PATH_SEPARATOR)){ + url = url.substring(url.indexOf(PATH_SEPARATOR) + 1); + } + return url; + } + } 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 de3cd3904d93223059bf0073cfe581bc6425be14..a7b4f05400e5712246701c4293ffd87bde2f59d9 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 @@ -20,6 +20,7 @@ import com.gitee.starblues.core.checker.PluginLauncherChecker; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.descriptor.PluginDescriptor; 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; @@ -43,7 +44,8 @@ import java.util.concurrent.ConcurrentHashMap; /** * 可引导启动的插件管理者 * @author starBlues - * @version 3.0.1 + * @since 3.0.0 + * @version 3.0.3 */ public class PluginLauncherManager extends DefaultPluginManager{ @@ -60,8 +62,7 @@ public class PluginLauncherManager extends DefaultPluginManager{ GenericApplicationContext applicationContext, IntegrationConfiguration configuration) { super(realizeProvider, configuration); - this.mainApplicationContext = - new MainApplicationContextProxy(applicationContext, configuration, applicationContext); + this.mainApplicationContext = new MainApplicationContextProxy(applicationContext, applicationContext); this.mainGenericApplicationContext = applicationContext; this.configuration = configuration; this.invokeSupperCache = new DefaultInvokeSupperCache(); @@ -124,6 +125,10 @@ public class PluginLauncherManager extends DefaultPluginManager{ registryInfo.remove(pluginId); super.stop(pluginInsideInfo); } catch (Exception e){ + if(e instanceof PluginProhibitStopException){ + // 禁止停止时, 不设置插件状态 + throw e; + } pluginInsideInfo.setPluginState(PluginState.STOPPED_FAILURE); throw e; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/CacheMainResourceMatcher.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/CacheMainResourceMatcher.java index ff906535551ae5627a5f1bc8c00bf0447c3a048c..84c2a4f3114566c2f3e3a33e71addfc207e591f8 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/CacheMainResourceMatcher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/CacheMainResourceMatcher.java @@ -23,10 +23,13 @@ import java.util.concurrent.ConcurrentHashMap; /** * 可缓存的 ResourceMatcher * @author starBlues + * @since 3.0.0 * @version 3.0.3 */ public class CacheMainResourceMatcher extends DefaultMainResourceMatcher implements AutoCloseable { + public static final String TYPE = "CacheMainResourceMatcher"; + private final Map resourceUrlMatchCache = new ConcurrentHashMap<>(); public CacheMainResourceMatcher(MainResourcePatternDefiner mainResourcePatternDefiner) { diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/DefaultMainResourceMatcher.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/DefaultMainResourceMatcher.java index 8c82daa4697b1b251646480678251e9a0a022d33..1dc02c3e090c1f41dac844985ff74beea94b2b3b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/DefaultMainResourceMatcher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/DefaultMainResourceMatcher.java @@ -17,6 +17,7 @@ package com.gitee.starblues.core.classloader; import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.UrlUtils; import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; @@ -26,15 +27,11 @@ import java.util.Set; /** * 默认的主程序资源匹配者 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public class DefaultMainResourceMatcher implements MainResourceMatcher{ - private static final String DEFAULT_PATH_SEPARATOR = "/"; - - private final static String SEPARATOR_DOT = "."; - private final static String SEPARATOR_BACKSLASH = "\\"; - private final Set includePatterns; private final Set excludePatterns; @@ -55,7 +52,7 @@ public class DefaultMainResourceMatcher implements MainResourceMatcher{ if(ObjectUtils.isEmpty(patterns) || ObjectUtils.isEmpty(url)){ return Boolean.FALSE; } - url = formatUrl(url); + url = UrlUtils.formatMatchUrl(url); for (String pattern : patterns) { boolean match = pathMatcher.match(pattern, url); if(match){ @@ -69,7 +66,7 @@ public class DefaultMainResourceMatcher implements MainResourceMatcher{ if(ObjectUtils.isEmpty(patterns) || ObjectUtils.isEmpty(url)){ return Boolean.FALSE; } - url = formatUrl(url); + url = UrlUtils.formatMatchUrl(url); for (String pattern : patterns) { boolean match = pathMatcher.match(pattern, url); if(match){ @@ -80,16 +77,5 @@ public class DefaultMainResourceMatcher implements MainResourceMatcher{ } - private String formatUrl(String url){ - if(url.contains(SEPARATOR_DOT)){ - url = url.replace(SEPARATOR_DOT, AntPathMatcher.DEFAULT_PATH_SEPARATOR); - } - if(url.contains(SEPARATOR_BACKSLASH)){ - url = url.replace(SEPARATOR_BACKSLASH, AntPathMatcher.DEFAULT_PATH_SEPARATOR); - } - if(url.startsWith(DEFAULT_PATH_SEPARATOR)){ - url = url.substring(url.indexOf(DEFAULT_PATH_SEPARATOR) + 1); - } - return url; - } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourcePatternDefiner.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourcePatternDefiner.java index 5759573f88aaf28dd30cc5d5ff4bbea8d61892b0..1a56fe38f1e925f7858b7f5b0f4d963db9bc532f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourcePatternDefiner.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourcePatternDefiner.java @@ -37,6 +37,4 @@ public interface MainResourcePatternDefiner { */ Set getExcludePatterns(); - - } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java b/spring-brick/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java index d63c7053293e7ecb19796d31dd123b10b31754af..a4a1389c20c3a34842a1d4d158dfab9dfe61b872 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/user/DefaultPluginUser.java @@ -25,6 +25,7 @@ import com.gitee.starblues.utils.SpringBeanCustomUtils; import org.springframework.context.support.GenericApplicationContext; import java.lang.annotation.Annotation; +import java.lang.reflect.Modifier; import java.util.*; /** @@ -148,7 +149,8 @@ public class DefaultPluginUser implements PluginUser{ * @param clazz clazz */ private void checkInterface(Class clazz) { - if (clazz.isInterface()) { + int modifiers = clazz.getModifiers(); + if (Modifier.isInterface(modifiers)|| Modifier.isAbstract(clazz.getModifiers())) { return; } throw new PluginException("[" + clazz.getName() + "]不是一个接口"); 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 d985065912be4679183f8071fb8112537ae678d8..b143ef55b6387454eabb5e143d605dacd86eddb5 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 @@ -16,6 +16,8 @@ package com.gitee.starblues.spring; +import com.gitee.starblues.spring.environment.EnvironmentProvider; + import java.util.Map; /** @@ -32,6 +34,14 @@ public interface MainApplicationContext extends ApplicationContext { */ Map> getConfigurableEnvironment(); + + /** + * 得到主程序配置的 Provider + * @return EnvironmentProvider + */ + EnvironmentProvider getEnvironmentProvider(); + + /** * 从主程序获取依赖 * 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 30d9f41c7fdf95c7feaaedb1b39a7016a4f94ba6..ea3bde458c14faa98d8202ac35d1615c5165d435 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 @@ -16,7 +16,8 @@ package com.gitee.starblues.spring; -import com.gitee.starblues.integration.IntegrationConfiguration; +import com.gitee.starblues.spring.environment.EnvironmentProvider; +import com.gitee.starblues.spring.environment.MainSpringBootEnvironmentProvider; import com.gitee.starblues.utils.ObjectUtils; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; @@ -38,23 +39,18 @@ import java.util.Map; public class MainApplicationContextProxy extends ApplicationContextProxy implements MainApplicationContext{ private final GenericApplicationContext applicationContext; - private final IntegrationConfiguration configuration; private final boolean isWebEnvironment; - public MainApplicationContextProxy(GenericApplicationContext applicationContext, - IntegrationConfiguration configuration) { + public MainApplicationContextProxy(GenericApplicationContext applicationContext) { super(applicationContext.getBeanFactory()); this.applicationContext = applicationContext; - this.configuration = configuration; this.isWebEnvironment = getIsWebEnvironment(applicationContext); } public MainApplicationContextProxy(GenericApplicationContext applicationContext, - IntegrationConfiguration configuration, AutoCloseable autoCloseable) { super(applicationContext.getBeanFactory(), autoCloseable); this.applicationContext = applicationContext; - this.configuration = configuration; this.isWebEnvironment = getIsWebEnvironment(applicationContext); } @@ -80,6 +76,11 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme return environmentMap; } + @Override + public EnvironmentProvider getEnvironmentProvider() { + return new MainSpringBootEnvironmentProvider(applicationContext.getEnvironment()); + } + @Override public Object resolveDependency(String requestingBeanName, Class dependencyType) { if(!ObjectUtils.isEmpty(requestingBeanName) && applicationContext.containsBean(requestingBeanName)){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/SpringBeanFactory.java b/spring-brick/src/main/java/com/gitee/starblues/spring/SpringBeanFactory.java index 8830eed81e85d88f54c787733e25aa814f7a1a8c..545728f1059c6cbed658b04aed8c874d46d27cee 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/SpringBeanFactory.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/SpringBeanFactory.java @@ -21,7 +21,9 @@ import org.springframework.beans.factory.ListableBeanFactory; /** * spring bean factory 封装接口 * @author starBlues + * @since 3.0.0 * @version 3.0.0 */ public interface SpringBeanFactory extends ListableBeanFactory { + } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/EmptyMainEnvironmentProvider.java b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/EmptyEnvironmentProvider.java similarity index 75% rename from spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/EmptyMainEnvironmentProvider.java rename to spring-brick/src/main/java/com/gitee/starblues/spring/environment/EmptyEnvironmentProvider.java index 8180226fff2cf9e92bb7b7ba1e5fd56c0ca417c0..69ca692d1c4d327f9d42bcdf4cbba9f9c4f65922 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/EmptyMainEnvironmentProvider.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/EmptyEnvironmentProvider.java @@ -14,18 +14,19 @@ * limitations under the License. */ -package com.gitee.starblues.bootstrap.realize; +package com.gitee.starblues.spring.environment; -import java.util.Collections; -import java.util.Map; +import java.util.function.BiConsumer; /** - * 主程序配置信息提供者空值实现 + * 空的配置信息提供者 * * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ -public class EmptyMainEnvironmentProvider implements MainEnvironmentProvider{ +public class EmptyEnvironmentProvider implements EnvironmentProvider{ + + @Override public Object getValue(String name) { return null; @@ -62,7 +63,12 @@ public class EmptyMainEnvironmentProvider implements MainEnvironmentProvider{ } @Override - public Map> getAll() { - return Collections.emptyMap(); + public EnvironmentProvider getByPrefix(String prefix) { + return new EmptyEnvironmentProvider(); + } + + @Override + public void forEach(BiConsumer action) { + } } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/MainEnvironmentProvider.java b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/EnvironmentProvider.java similarity index 80% rename from spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/MainEnvironmentProvider.java rename to spring-brick/src/main/java/com/gitee/starblues/spring/environment/EnvironmentProvider.java index ea68a164bec6f04e3b4c5e32c73b51c1f778c8b6..a4e1facb83aa4f4340098a90b66e4d9b5c90abc8 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/MainEnvironmentProvider.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/EnvironmentProvider.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.gitee.starblues.bootstrap.realize; +package com.gitee.starblues.spring.environment; -import java.util.Map; +import java.util.function.BiConsumer; /** - * 主程序配置信息提供者 + * 配置信息提供者接口 * * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ -public interface MainEnvironmentProvider { +public interface EnvironmentProvider { /** * 根据名称获取配置值 @@ -75,10 +75,18 @@ public interface MainEnvironmentProvider { */ Boolean getBoolean(String name); + /** + * 根据前缀名称批量获取配置值 + * @param prefix 前缀 + * @return 环境 + */ + EnvironmentProvider getByPrefix(String prefix); + /** * 获取所有配置集合 - * @return Map + * @param action 每个条目执行的操作 */ - Map> getAll(); + void forEach(BiConsumer action); + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/environment/MainSpringBootEnvironmentProvider.java b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/MainSpringBootEnvironmentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..84106b311e1410101e580cb9460a4cc1130fcae4 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/MainSpringBootEnvironmentProvider.java @@ -0,0 +1,108 @@ +/** + * 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.spring.environment; + +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.ObjectValueUtils; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +/** + * 主程序配置信息提供者实现 + * + * @author starBlues + * @version 3.0.3 + */ +public class MainSpringBootEnvironmentProvider implements EnvironmentProvider { + + private final ConfigurableEnvironment environment; + + public MainSpringBootEnvironmentProvider(ConfigurableEnvironment environment) { + this.environment = environment; + } + + @Override + public Object getValue(String name) { + MutablePropertySources propertySources = environment.getPropertySources(); + for (PropertySource propertySource : propertySources) { + Object property = propertySource.getProperty(name); + if (property != null) { + return property; + } + } + return null; + } + + @Override + public String getString(String name) { + return ObjectValueUtils.getString(getValue(name)); + } + + @Override + public Integer getInteger(String name) { + return ObjectValueUtils.getInteger(getValue(name)); + } + + @Override + public Long getLong(String name) { + return ObjectValueUtils.getLong(getValue(name)); + } + + @Override + public Double getDouble(String name) { + return ObjectValueUtils.getDouble(getValue(name)); + } + + @Override + public Float getFloat(String name) { + return ObjectValueUtils.getFloat(getValue(name)); + } + + @Override + public Boolean getBoolean(String name) { + return ObjectValueUtils.getBoolean(getValue(name)); + } + + @Override + public EnvironmentProvider getByPrefix(String prefix) { + if(ObjectUtils.isEmpty(prefix)){ + return new EmptyEnvironmentProvider(); + } + Map collect = new LinkedHashMap<>(); + MutablePropertySources propertySources = environment.getPropertySources(); + for (PropertySource propertySource : propertySources) { + String name = propertySource.getName(); + if(name.startsWith(prefix)){ + collect.put(MapEnvironmentProvider.resolveKey(prefix, name), propertySource.getSource()); + } + } + return new MapEnvironmentProvider(collect); + } + + @Override + public void forEach(BiConsumer action) { + MutablePropertySources propertySources = environment.getPropertySources(); + for (PropertySource propertySource : propertySources) { + action.accept(propertySource.getName(), propertySource.getSource()); + } + } +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/MapEnvironmentProvider.java similarity index 36% rename from spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java rename to spring-brick/src/main/java/com/gitee/starblues/spring/environment/MapEnvironmentProvider.java index f71a363c300da964609be23baf3ff280501803e7..6a25cb14b55eba3eeafdd791377eacab9c3ec777 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/environment/MapEnvironmentProvider.java @@ -14,94 +14,106 @@ * limitations under the License. */ -package com.gitee.starblues.bootstrap.realize; +package com.gitee.starblues.spring.environment; -import com.gitee.starblues.loader.utils.ObjectUtils; -import com.gitee.starblues.spring.MainApplicationContext; -import com.gitee.starblues.utils.MapValueGetter; +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.ObjectValueUtils; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.Function; +import java.util.function.BiConsumer; /** - * 主程序配置信息提供者默认实现 + * map类型的配置信息提供者 * * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ -public class DefaultMainEnvironmentProvider implements MainEnvironmentProvider{ +public class MapEnvironmentProvider implements EnvironmentProvider{ - private final MainApplicationContext mainApplicationContext; + private final String prefix; + private final Map source; - public DefaultMainEnvironmentProvider(MainApplicationContext mainApplicationContext) { - this.mainApplicationContext = mainApplicationContext; + public MapEnvironmentProvider(Map source){ + this(null, source); } - @Override - public Object getValue(String name) { - Map> configurableEnvironment = mainApplicationContext.getConfigurableEnvironment(); - if(ObjectUtils.isEmpty(configurableEnvironment)){ - return null; + public MapEnvironmentProvider(String prefix, Map source) { + if(prefix == null){ + this.prefix = ""; + } else { + this.prefix = prefix; } - for (Map.Entry> entry : configurableEnvironment.entrySet()) { - Map value = entry.getValue(); - Object o = value.get(name); - if(o != null){ - return o; - } + if(ObjectUtils.isEmpty(source)){ + this.source = Collections.emptyMap(); + } else { + this.source = source; + } + } + + public static String resolveKey(String prefix, String name){ + String key = name.replace(prefix, ""); + int i = key.indexOf("."); + if(i > -1){ + key = key.substring(i + 1); } - return null; + return key; + } + + @Override + public Object getValue(String name) { + String key = prefix + name; + return source.get(key); } @Override public String getString(String name) { - return getMapValueGetter(name).getString(name); + return ObjectValueUtils.getString(getValue(name)); } @Override public Integer getInteger(String name) { - return getMapValueGetter(name).getInteger(name); + return ObjectValueUtils.getInteger(getValue(name)); } @Override public Long getLong(String name) { - return getMapValueGetter(name).getLong(name); + return ObjectValueUtils.getLong(getValue(name)); } @Override public Double getDouble(String name) { - return getMapValueGetter(name).getDouble(name); + return ObjectValueUtils.getDouble(getValue(name)); } @Override public Float getFloat(String name) { - return getMapValueGetter(name).getFloat(name); + return ObjectValueUtils.getFloat(getValue(name)); } @Override public Boolean getBoolean(String name) { - return getMapValueGetter(name).getBoolean(name); + return ObjectValueUtils.getBoolean(getValue(name)); } @Override - public Map> getAll() { - return mainApplicationContext.getConfigurableEnvironment(); - } - - private MapValueGetter getMapValueGetter(String name) { - Map> configurableEnvironment = mainApplicationContext.getConfigurableEnvironment(); - if(ObjectUtils.isEmpty(configurableEnvironment)){ - return new MapValueGetter(Collections.emptyMap()); + public EnvironmentProvider getByPrefix(String prefix) { + if(ObjectUtils.isEmpty(prefix)){ + return new EmptyEnvironmentProvider(); } - for (Map.Entry> entry : configurableEnvironment.entrySet()) { - Map value = entry.getValue(); - if(value.containsKey(name)){ - return new MapValueGetter(value); + Map collect = new LinkedHashMap<>(); + source.forEach((k,v)->{ + if(k.startsWith(prefix)){ + collect.put(resolveKey(prefix, k), v); } - } - return new MapValueGetter(Collections.emptyMap()); + }); + return new MapEnvironmentProvider(collect); } + @Override + public void forEach(BiConsumer action) { + source.forEach(action); + } } 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 4e6c89aae416b53e2f31b50075caa6fdebe14841..3a2d192d20ef505ed637d20932f6d4839892c66e 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 @@ -108,8 +108,8 @@ public class PluginStaticResourceResolver extends AbstractResourceResolver { } // 查找第一级节点,找不到则读取根index.html - if(partialPath.contains(UrlUtils.SPLIT)){ - partialPath = partialPath.substring(0, partialPath.indexOf(UrlUtils.SPLIT)); + if(partialPath.contains(UrlUtils.PATH_SEPARATOR)){ + partialPath = partialPath.substring(0, partialPath.indexOf(UrlUtils.PATH_SEPARATOR)); } // 第一级节点 resource = findResource(pluginResource, UrlUtils.joiningUrlPath(partialPath, indexPageName)); @@ -117,7 +117,7 @@ public class PluginStaticResourceResolver extends AbstractResourceResolver { return resource; } // 根节点 - return findResource(pluginResource, UrlUtils.joiningUrlPath(UrlUtils.SPLIT, indexPageName)); + return findResource(pluginResource, UrlUtils.joiningUrlPath(UrlUtils.PATH_SEPARATOR, indexPageName)); } } diff --git a/update.md b/update.md index 534b664b07b8c0acfbd981bd60740fec593678d0..6bbe377578eb573664e693f3fa5193b7283d6946 100644 --- a/update.md +++ b/update.md @@ -1,13 +1,20 @@ -1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 插件可触发`WebServerInitializedEvent`类型的事件 -2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) -3. 【新增】插件新增`@AutowiredType`注解, 可指定依赖注入类型 -4. 【新增】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) -5. 【优化】优化静态资源文件加载问题 -6. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` -7. 【优化】优化从主程序依赖加载`Class`资源模块 -8. 【优化】优化插件中注入异常提示 -9. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -10. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -11. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 -12. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 -13. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 +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`问题 + + +- 注意: 本次升级后, 从主程序注入的`Bean`, 需设置注入类型, 详见文档: [插件中注入主程序Bean说明](https://www.yuque.com/starblues/spring-brick-3.0.0/vot8gg) \ No newline at end of file