From 5d8fa4acd8a4d9e995b8fd2a4048710de85e5e12 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sat, 21 May 2022 17:30:02 +0800 Subject: [PATCH 01/11] update to 3.0.0 --- pom.xml | 2 +- spring-brick-bootstrap/pom.xml | 2 +- .../EmptyMainApplicationContext.java | 12 +- .../bootstrap/PluginApplicationContext.java | 5 +- .../PluginDisableAutoConfiguration.java | 72 +++++++ .../bootstrap/PluginListableBeanFactory.java | 188 +++++++++++++++-- .../bootstrap/PluginSpringApplication.java | 7 +- .../PluginWebApplicationContext.java | 96 +++++++++ ...lveHttpMessageConvertersConfiguration.java | 41 ++++ .../PluginApplicationWebEventListener.java | 82 ++++++++ .../ComposeSpringPluginProcessor.java | 6 +- .../web/PluginControllerProcessor.java | 198 ++++++++---------- .../main/resources/META-INF/spring.factories | 7 + spring-brick-common/pom.xml | 2 +- spring-brick-loader/pom.xml | 2 +- spring-brick-maven-packager/pom.xml | 2 +- .../pack/AbstractDependencyFilterMojo.java | 6 + .../plugin/pack/BasicRepackager.java | 3 +- .../starblues/plugin/pack/dev/DevConfig.java | 5 + .../plugin/pack/dev/DevRepackager.java | 10 +- .../plugin/pack/main/JarOuterPackager.java | 24 ++- .../plugin-help.xml | 35 ++-- .../main/resources/META-INF/maven/plugin.xml | 35 ++-- spring-brick/pom.xml | 2 +- .../starblues/core/DefaultPluginManager.java | 4 +- .../starblues/core/PluginLauncherManager.java | 3 +- .../PluginMainResourcePatternDefiner.java | 7 +- .../AutoIntegrationConfiguration.java | 4 +- .../ExtendPointWebConfiguration.java | 7 + .../spring/MainApplicationContext.java | 15 ++ .../spring/MainApplicationContextProxy.java | 31 ++- .../ResolvePluginThreadClassLoader.java | 71 +++++++ update.md | 16 +- 33 files changed, 791 insertions(+), 211 deletions(-) create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.java create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ResolveHttpMessageConvertersConfiguration.java create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/listener/PluginApplicationWebEventListener.java create mode 100644 spring-brick-bootstrap/src/main/resources/META-INF/spring.factories create mode 100644 spring-brick/src/main/java/com/gitee/starblues/spring/ResolvePluginThreadClassLoader.java diff --git a/pom.xml b/pom.xml index c715765..0970aa1 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.gitee.starblues spring-brick-parent pom - 3.0.2 + 3.0.3 spring-brick-common diff --git a/spring-brick-bootstrap/pom.xml b/spring-brick-bootstrap/pom.xml index 730adc0..cf32d07 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.2 + 3.0.3 spring-brick-bootstrap 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 0321276..e4ddb24 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 @@ -25,7 +25,7 @@ import java.util.Set; /** * 空的MainApplicationContext实现 * @author starBlues - * @version 3.0.1 + * @version 3.0.3 */ public class EmptyMainApplicationContext implements MainApplicationContext { @@ -46,4 +46,14 @@ public class EmptyMainApplicationContext implements MainApplicationContext { return Collections.emptyMap(); } + @Override + public boolean isResolveDependency(String packageName) { + return false; + } + + @Override + public boolean isWebEnvironment() { + return false; + } + } 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 2ed37d0..b6c9cb1 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,12 +20,14 @@ 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; /** * 插件ApplicationContext实现 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class PluginApplicationContext extends AnnotationConfigApplicationContext { @@ -57,4 +59,5 @@ public class PluginApplicationContext extends AnnotationConfigApplicationContext public void close() { super.close(); } + } 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 new file mode 100644 index 0000000..7c69c39 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginDisableAutoConfiguration.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.bootstrap; + +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; + +/** + * 插件禁用的 AutoConfiguration + * + * @author starBlues + * @version 3.0.3 + */ +public class PluginDisableAutoConfiguration implements AutoConfigurationImportFilter { + + private static final List DISABLE_FUZZY_CLASSES = new ArrayList<>(); + + public PluginDisableAutoConfiguration(){ + addDisableFuzzyClasses(); + } + + 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"); + } + + public static boolean isDisabled(String className){ + if(ObjectUtils.isEmpty(className)){ + return false; + } + for (String disableFuzzyClass : DISABLE_FUZZY_CLASSES) { + if (className.contains(disableFuzzyClass)) { + return true; + } + } + return false; + } + + @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] = !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 fda8129..5d1a873 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 @@ -21,25 +21,35 @@ import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.utils.ObjectUtils; import com.gitee.starblues.utils.ReflectionUtils; +import lombok.AllArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; +import org.springframework.beans.factory.BeanFactory; 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.core.ResolvableType; import org.springframework.lang.Nullable; +import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Stream; /** * 插件BeanFactory实现 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class PluginListableBeanFactory extends DefaultListableBeanFactory { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Logger logger = LoggerFactory.getLogger(PluginListableBeanFactory.class); private final MainApplicationContext applicationContext; @@ -47,20 +57,55 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { this.applicationContext = applicationContext; } + @SuppressWarnings("unchecked") @Override public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { - + if(isDisabled(descriptor)){ + return resolveDependencyFromMain(descriptor, false); + } try { - return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); + Object object = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + typeConverter); + + if(object instanceof ObjectProvider){ + return new PluginObjectProviderWrapper((ObjectProvider) object, descriptor); + } + return object; } catch (BeansException e){ - return resolveDependencyFromMain(descriptor); + if(e instanceof NoSuchBeanDefinitionException){ + Object dependencyBean = resolveDependencyFromMain(descriptor, true); + if(dependencyBean != null){ + return dependencyBean; + } + } + throw e; + } + } + + @Override + public void destroySingletons() { + String[] beanDefinitionNames = getBeanDefinitionNames(); + for (String beanDefinitionName : beanDefinitionNames) { + destroyBean(beanDefinitionName); } + super.destroySingletons(); + destroyAll(); } - private Object resolveDependencyFromMain(DependencyDescriptor descriptor){ + @Override + public ObjectProvider getBeanProvider(Class requiredType, boolean allowEagerInit) { + return super.getBeanProvider(requiredType, allowEagerInit); + } + + + private Object resolveDependencyFromMain(DependencyDescriptor descriptor, boolean isResolveDependency){ + String packageName = descriptor.getDependencyType().getPackage().getName(); + if(isResolveDependency && !applicationContext.isResolveDependency(packageName)){ + return null; + } String dependencyName = descriptor.getDependencyName(); SpringBeanFactory springBeanFactory = applicationContext.getSpringBeanFactory(); if(!ObjectUtils.isEmpty(dependencyName) && springBeanFactory.containsBean(dependencyName)){ @@ -74,16 +119,6 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { } } - @Override - public void destroySingletons() { - String[] beanDefinitionNames = getBeanDefinitionNames(); - for (String beanDefinitionName : beanDefinitionNames) { - destroyBean(beanDefinitionName); - } - super.destroySingletons(); - destroyAll(); - } - private void destroyAll(){ ReflectionUtils.findField(this.getClass(), field -> { field.setAccessible(true); @@ -97,4 +132,125 @@ 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 { + + private final ObjectProvider pluginObjectProvider; + private final DependencyDescriptor descriptor; + + @Override + public Object getObject() throws BeansException { + if(isDisabled(descriptor)){ + return resolveDependencyFromMain(descriptor, false); + } + 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); + } + return pluginObjectProvider.getObject(args); + } + + @Override + @Nullable + public Object getIfAvailable() throws BeansException { + if(isDisabled(descriptor)){ + try { + return getObject(); + } catch (Exception e){ + return null; + } + } else { + return pluginObjectProvider.getIfAvailable(); + } + } + + @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); + } + } + + @Override + @Nullable + public Object getIfUnique() throws BeansException { + if(isDisabled(descriptor)){ + Object dependency = getIfAvailable(); + if(dependency == null){ + return Optional.empty(); + } else { + return Optional.of(dependency); + } + } else { + return pluginObjectProvider.getIfUnique(); + } + } + + @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); + } + } + + @Override + public Stream stream() { + if(isDisabled(descriptor)){ + return getStreamOfMain(); + } else { + return pluginObjectProvider.stream(); + } + } + + @Override + public Stream orderedStream() { + if(isDisabled(descriptor)){ + // TODO 随意排序 + return getStreamOfMain().sorted(); + } else { + return pluginObjectProvider.orderedStream(); + } + } + + @SuppressWarnings("unchecked") + private Stream getStreamOfMain(){ + SpringBeanFactory springBeanFactory = applicationContext.getSpringBeanFactory(); + Map beansOfType = springBeanFactory.getBeansOfType(descriptor.getDependencyType()); + if(beansOfType.isEmpty()){ + return Stream.empty(); + } else { + return (Stream) beansOfType.values().stream(); + } + } + } + } 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 59a7002..8ac00e9 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 @@ -34,11 +34,11 @@ import org.springframework.core.io.ResourceLoader; /** * 插件SpringApplication实现 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class PluginSpringApplication extends SpringApplication { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Logger logger = LoggerFactory.getLogger(PluginSpringApplication.class); private final ProcessorContext.RunMode runMode; @@ -68,6 +68,9 @@ public class PluginSpringApplication extends SpringApplication { protected GenericApplicationContext getApplicationContext(){ if(runMode == ProcessorContext.RunMode.ONESELF){ return (GenericApplicationContext) super.createApplicationContext(); + } + if(processorContext.getMainApplicationContext().isWebEnvironment()){ + return new PluginWebApplicationContext(beanFactory, processorContext); } else { return new PluginApplicationContext(beanFactory, processorContext); } 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 new file mode 100644 index 0000000..64bb67f --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginWebApplicationContext.java @@ -0,0 +1,96 @@ +/** + * 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.listener.PluginApplicationWebEventListener; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; +import com.gitee.starblues.bootstrap.realize.DefaultMainEnvironmentProvider; +import com.gitee.starblues.bootstrap.realize.MainEnvironmentProvider; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerException; + +/** + * 主程序为 web 类型时创建的插件 ApplicationContext + * + * @author starBlues + * @version 3.0.3 + */ +public class PluginWebApplicationContext extends PluginApplicationContext implements WebServerApplicationContext { + + private final WebServer webServer; + private final String serverNamespace; + + public PluginWebApplicationContext(DefaultListableBeanFactory beanFactory, ProcessorContext processorContext) { + super(beanFactory, processorContext); + MainEnvironmentProvider environmentProvider = new DefaultMainEnvironmentProvider( + processorContext.getMainApplicationContext()); + this.webServer = new PluginSimulationWebServer(environmentProvider); + this.serverNamespace = processorContext.getPluginDescriptor().getPluginId(); + addApplicationListener(new PluginApplicationWebEventListener(this)); + } + + @Override + public WebServer getWebServer() { + return webServer; + } + + @Override + public String getServerNamespace() { + return serverNamespace; + } + + + public static class PluginSimulationWebServer implements WebServer { + + private final int port; + + public PluginSimulationWebServer(MainEnvironmentProvider environmentProvider) { + Integer port = environmentProvider.getInteger("server.port"); + if(port == null){ + this.port = -1; + } else { + this.port = port; + } + } + + @Override + public void start() throws WebServerException { + throw new InvalidWebServerException(); + } + + @Override + public void stop() throws WebServerException { + throw new InvalidWebServerException(); + } + + @Override + public int getPort() { + return port; + } + + } + + public static class InvalidWebServerException extends WebServerException{ + + public InvalidWebServerException() { + super("Invalid operation", null); + } + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ResolveHttpMessageConvertersConfiguration.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ResolveHttpMessageConvertersConfiguration.java new file mode 100644 index 0000000..5490027 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/ResolveHttpMessageConvertersConfiguration.java @@ -0,0 +1,41 @@ +/** + * 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 org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.http.converter.HttpMessageConverter; + +import java.util.stream.Collectors; + +/** + * resolve config HttpMessageConverters bean + * + * @author starBlues + * @version 3.0.3 + */ +public class ResolveHttpMessageConvertersConfiguration { + + @Bean + @ConditionalOnMissingBean + public HttpMessageConverters messageConverters(ObjectProvider> converters) { + return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList())); + } + +} diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/listener/PluginApplicationWebEventListener.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/listener/PluginApplicationWebEventListener.java new file mode 100644 index 0000000..6865401 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/listener/PluginApplicationWebEventListener.java @@ -0,0 +1,82 @@ +/** + * 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.listener; + +import com.gitee.starblues.bootstrap.PluginWebApplicationContext; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.ResolvableType; + +/** + * 插件监听器扩展 + * + * @author starBlues + * @version 3.0.3 + */ +public class PluginApplicationWebEventListener implements ApplicationListener { + + + private final PluginWebApplicationContext applicationContext; + + public PluginApplicationWebEventListener(PluginWebApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof ApplicationReadyEvent) { + callWebServerInitializedEvent(); + } + } + + @SuppressWarnings("all") + protected void callWebServerInitializedEvent(){ + String[] beanNamesForType = applicationContext.getBeanNamesForType(ResolvableType.forClassWithGenerics( + ApplicationListener.class, WebServerInitializedEvent.class + )); + PluginWebServerInitializedEvent pluginWebServerInitializedEvent = + new PluginWebServerInitializedEvent(applicationContext); + for (String beanName : beanNamesForType) { + try { + ApplicationListener applicationListener = + (ApplicationListener) applicationContext.getBean(beanName); + applicationListener.onApplicationEvent(pluginWebServerInitializedEvent); + } catch (Exception e){ + e.printStackTrace(); + } + } + } + + public static class PluginWebServerInitializedEvent extends WebServerInitializedEvent{ + + private final PluginWebApplicationContext pluginWebApplicationContext; + + protected PluginWebServerInitializedEvent(PluginWebApplicationContext pluginWebApplicationContext) { + super(pluginWebApplicationContext.getWebServer()); + this.pluginWebApplicationContext = pluginWebApplicationContext; + } + + @Override + public WebServerApplicationContext getApplicationContext() { + return pluginWebApplicationContext; + } + } + +} 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 05d4847..63e7911 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 @@ -38,7 +38,7 @@ import java.util.stream.Collectors; /** * 组合的处理器 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class ComposeSpringPluginProcessor implements SpringPluginProcessor { @@ -160,6 +160,10 @@ public class ComposeSpringPluginProcessor implements SpringPluginProcessor { * @param processors 处理者容器集合 */ protected void addDefaultWebEnvProcessors(ProcessorContext context, List processors){ + if(!context.getMainApplicationContext().isWebEnvironment()){ + // 主程序不是web类型, 则不进行注册 + return; + } SpringPluginBootstrap springPluginBootstrap = context.getSpringPluginBootstrap(); DisablePluginWeb disablePluginWeb = AnnotationUtils.findAnnotation(springPluginBootstrap.getClass(), DisablePluginWeb.class); 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 a097e64..a23b314 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 @@ -24,6 +24,9 @@ import com.gitee.starblues.bootstrap.utils.DestroyUtils; import com.gitee.starblues.integration.IntegrationConfiguration; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.utils.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -43,7 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * 插件Controller处理者 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class PluginControllerProcessor implements SpringPluginProcessor { @@ -53,7 +56,6 @@ public class PluginControllerProcessor implements SpringPluginProcessor { private RequestMappingHandlerMapping requestMappingHandlerMapping; - private Method getMappingForMethod; private RequestMappingHandlerAdapter handlerAdapter; private final AtomicBoolean canRegistered = new AtomicBoolean(false); @@ -65,13 +67,6 @@ public class PluginControllerProcessor implements SpringPluginProcessor { this.requestMappingHandlerMapping = mainBeanFactory.getBean(RequestMappingHandlerMapping.class); this.handlerAdapter = SpringBeanCustomUtils.getExistBean(processorContext.getMainApplicationContext(), RequestMappingHandlerAdapter.class); - this.getMappingForMethod = ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, - "getMappingForMethod", Method.class, Class.class); - if(getMappingForMethod == null){ - LOG.warn("RequestMappingHandlerMapping 类中没有发现 方法, 无法注册插件接口. " + - "请检查当前环境是否为 web 环境"); - } - this.getMappingForMethod.setAccessible(true); canRegistered.set(true); } @@ -91,12 +86,6 @@ public class PluginControllerProcessor implements SpringPluginProcessor { if(!canRegistered.get()){ return; } - IntegrationConfiguration configuration = processorContext.getConfiguration(); - if(ObjectUtils.isEmpty(configuration.pluginRestPathPrefix()) - && !configuration.enablePluginIdRestPathPrefix()){ - // 如果 pluginRestPathPrefix 为空, 并且没有启用插件id作为插件前缀, 则不进行修改插件controller地址前缀 - return; - } String pluginId = processorContext.getPluginDescriptor().getPluginId(); List controllerWrappers = processorContext.getRegistryInfo(PROCESS_CONTROLLERS); if(ObjectUtils.isEmpty(controllerWrappers)){ @@ -105,21 +94,31 @@ public class PluginControllerProcessor implements SpringPluginProcessor { GenericApplicationContext applicationContext = processorContext.getApplicationContext(); Iterator iterator = controllerWrappers.iterator(); + + PluginRequestMappingHandlerMapping pluginHandlerMapping = new PluginRequestMappingHandlerMapping(); + + while (iterator.hasNext()){ ControllerWrapper controllerWrapper = iterator.next(); if(!applicationContext.containsBean(controllerWrapper.getBeanName())){ iterator.remove(); } Object controllerBean = applicationContext.getBean(controllerWrapper.getBeanName()); - Set requestMappingInfos = registry(applicationContext, controllerBean.getClass()); - if(requestMappingInfos.isEmpty()){ - iterator.remove(); - } else { - for (RequestMappingInfo requestMappingInfo : requestMappingInfos) { - LOG.info("插件[{}]注册接口: {}", pluginId, requestMappingInfo.toString()); - } - controllerWrapper.setRequestMappingInfos(requestMappingInfos); + pluginHandlerMapping.registerHandler(controllerBean); + List registerMappingInfo = pluginHandlerMapping.getAndClear(); + + Set requestMappingInfoSet = new HashSet<>(registerMappingInfo.size()); + for (RegisterMappingInfo mappingInfo : registerMappingInfo) { + RequestMappingInfo requestMappingInfo = mappingInfo.getRequestMappingInfo(); + requestMappingHandlerMapping.registerMapping( + requestMappingInfo, + mappingInfo.getHandler(), + mappingInfo.getMethod() + ); + LOG.info("插件[{}]注册接口: {}", pluginId, requestMappingInfo); + requestMappingInfoSet.add(requestMappingInfo); } + controllerWrapper.setRequestMappingInfo(requestMappingInfoSet); } } @@ -140,36 +139,14 @@ public class PluginControllerProcessor implements SpringPluginProcessor { return ProcessorContext.RunMode.PLUGIN; } - - private Set registry(GenericApplicationContext pluginApplicationContext, Class aClass) - throws ProcessorException { - Object object = pluginApplicationContext.getBean(aClass); - - Method[] methods = aClass.getDeclaredMethods(); - Set requestMappingInfos = new HashSet<>(); - for (Method method : methods) { - if (isHaveRequestMapping(method)) { - try { - RequestMappingInfo requestMappingInfo = (RequestMappingInfo) - getMappingForMethod.invoke(requestMappingHandlerMapping, method, aClass); - requestMappingHandlerMapping.registerMapping(requestMappingInfo, object, method); - requestMappingInfos.add(requestMappingInfo); - } catch (Exception e){ - throw new ProcessorException(e.getMessage()); - } - } - } - return requestMappingInfos; - } - /** * 卸载具体的Controller操作 * @param controllerBeanWrapper controllerBean包装 */ private void unregister(ControllerWrapper controllerBeanWrapper) { - Set requestMappingInfos = controllerBeanWrapper.getRequestMappingInfos(); - if(requestMappingInfos != null && !requestMappingInfos.isEmpty()){ - for (RequestMappingInfo requestMappingInfo : requestMappingInfos) { + Set requestMappingInfoSet = controllerBeanWrapper.getRequestMappingInfo(); + if(requestMappingInfoSet != null && !requestMappingInfoSet.isEmpty()){ + for (RequestMappingInfo requestMappingInfo : requestMappingInfoSet) { requestMappingHandlerMapping.unregisterMapping(requestMappingInfo); } } @@ -181,15 +158,6 @@ public class PluginControllerProcessor implements SpringPluginProcessor { } } - /** - * 方法上是否存在 @RequestMapping 注解 - * @param method method - * @return boolean - */ - private boolean isHaveRequestMapping(Method method){ - return AnnotationUtils.findAnnotation(method, RequestMapping.class) != null; - } - private static class ChangeRestPathPostProcessor implements BeanPostProcessor { private final static Logger LOG = LoggerFactory.getLogger(ChangeRestPathPostProcessor.class); @@ -201,6 +169,7 @@ public class PluginControllerProcessor implements SpringPluginProcessor { this.processorContext = processorContext; } + @SuppressWarnings("unchecked") @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { Class aClass = bean.getClass(); @@ -218,45 +187,16 @@ public class PluginControllerProcessor implements SpringPluginProcessor { String pluginId = processorContext.getPluginDescriptor().getPluginId(); IntegrationConfiguration configuration = processorContext.getConfiguration(); String pathPrefix = PluginConfigUtils.getPluginRestPrefix(configuration, pluginId); - - if(ObjectUtils.isEmpty(pathPrefix)){ - LOG.error("插件 [{}] Controller类 [{}] 未发现 path 配置, {}", - pluginId, aClass.getSimpleName(), COMMON_ERROR); - return; - } - Set definePaths = new HashSet<>(); - definePaths.addAll(Arrays.asList(requestMapping.path())); - definePaths.addAll(Arrays.asList(requestMapping.value())); try { - Map memberValues = ClassUtils.getAnnotationsUpdater(requestMapping); - if(memberValues == null){ - LOG.error("插件 [{}] Controller 类 [{}] 无法反射获取注解属性, {}", - pluginId, aClass.getSimpleName(), COMMON_ERROR); - return; + if(!ObjectUtils.isEmpty(pathPrefix)){ + resolvePathPrefix(pathPrefix, aClass, requestMapping); } - 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 }; - } - memberValues.put("path", newPath); - memberValues.put("value", newPath); - List controllerWrappers = processorContext.getRegistryInfo(PROCESS_CONTROLLERS); if(controllerWrappers == null){ controllerWrappers = new ArrayList<>(); processorContext.addRegistryInfo(PROCESS_CONTROLLERS, controllerWrappers); } ControllerWrapper controllerWrapper = new ControllerWrapper(); - controllerWrapper.setPathPrefix(newPath); controllerWrapper.setBeanName(beanName); controllerWrapper.setBeanClass(aClass); controllerWrappers.add(controllerWrapper); @@ -264,9 +204,41 @@ public class PluginControllerProcessor implements SpringPluginProcessor { 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 }; + } + memberValues.put("path", newPath); + memberValues.put("value", newPath); + } + + } + @Data static class ControllerWrapper{ /** @@ -274,11 +246,6 @@ public class PluginControllerProcessor implements SpringPluginProcessor { */ private String beanName; - /** - * controller 路径前缀 - */ - private String[] pathPrefix; - /** * controller bean 类型 */ @@ -287,39 +254,38 @@ public class PluginControllerProcessor implements SpringPluginProcessor { /** * controller 的 RequestMappingInfo 集合 */ - private Set requestMappingInfos; + private Set requestMappingInfo; + } - public Class getBeanClass() { - return beanClass; - } - public void setBeanClass(Class beanClass) { - this.beanClass = beanClass; - } + private static class PluginRequestMappingHandlerMapping extends RequestMappingHandlerMapping { - public String getBeanName() { - return beanName; - } + private final List registerMappingInfo = new ArrayList<>(); - public void setBeanName(String beanName) { - this.beanName = beanName; + public void registerHandler(Object handler){ + detectHandlerMethods(handler); } - public String[] getPathPrefix() { - return pathPrefix; + @Override + protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { + super.registerHandlerMethod(handler, method, mapping); + registerMappingInfo.add(new RegisterMappingInfo(handler, method, mapping)); } - public void setPathPrefix(String[] pathPrefix) { - this.pathPrefix = pathPrefix; + public List getAndClear(){ + List registerMappingInfo = new ArrayList<>(this.registerMappingInfo); + this.registerMappingInfo.clear(); + return registerMappingInfo; } - public Set getRequestMappingInfos() { - return requestMappingInfos; - } + } - public void setRequestMappingInfos(Set requestMappingInfos) { - this.requestMappingInfos = requestMappingInfos; - } + @AllArgsConstructor + @Getter + private static class RegisterMappingInfo{ + private final Object handler; + private final Method method; + private final RequestMappingInfo requestMappingInfo; } } diff --git a/spring-brick-bootstrap/src/main/resources/META-INF/spring.factories b/spring-brick-bootstrap/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..9d17993 --- /dev/null +++ b/spring-brick-bootstrap/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +# Auto Configuration Import Filters +org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ +com.gitee.starblues.bootstrap.PluginDisableAutoConfiguration + +# Auto Configure +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.gitee.starblues.bootstrap.ResolveHttpMessageConvertersConfiguration \ No newline at end of file diff --git a/spring-brick-common/pom.xml b/spring-brick-common/pom.xml index f5213b9..98f6c36 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.2 + 3.0.3 spring-brick-common diff --git a/spring-brick-loader/pom.xml b/spring-brick-loader/pom.xml index 2df4213..2b61cd0 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.2 + 3.0.3 4.0.0 diff --git a/spring-brick-maven-packager/pom.xml b/spring-brick-maven-packager/pom.xml index 10d4c6b..cb70eb6 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.2 + 3.0.3 spring-brick-maven-packager diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java index 42e0e14..19505ea 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java @@ -95,6 +95,12 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { excludes.add(Exclude.get("org.springframework.boot", "spring-boot-starter-json")); excludes.add(Exclude.get("org.springframework", "spring-webmvc")); excludes.add(Exclude.get("org.springframework", "spring-web")); + + // jackson + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-core")); + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-databind")); + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-annotations")); + excludes.add(Exclude.get("com.fasterxml.jackson.module", "jackson-module-parameter-names")); } } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java index bb1f790..44bc3a5 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java @@ -32,6 +32,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.*; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -237,7 +238,7 @@ public class BasicRepackager implements Repackager{ protected String writePluginMetaInfo(Properties properties) throws Exception { File pluginMetaFile = createPluginMetaFile(); try (OutputStreamWriter writer = new OutputStreamWriter( - new FileOutputStream(pluginMetaFile), StandardCharsets.UTF_8)){ + Files.newOutputStream(pluginMetaFile.toPath()), StandardCharsets.UTF_8)){ properties.store(writer, Constant.PLUGIN_METE_COMMENTS); return pluginMetaFile.getPath(); } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java index 20ed1b6..9070a6e 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java @@ -34,4 +34,9 @@ public class DevConfig { */ private List moduleDependencies; + /** + * 本地jar依赖文件定义 + */ + private List localJars; + } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java index 9e436c2..6540b3f 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java @@ -44,11 +44,19 @@ public class DevRepackager extends BasicRepackager { @Override protected Set getDependenciesIndexSet() throws Exception { - moduleDependencies = getModuleDependencies(repackageMojo.getDevConfig()); + DevConfig devConfig = repackageMojo.getDevConfig(); + if(devConfig == null){ + return super.getDependenciesIndexSet(); + } + moduleDependencies = getModuleDependencies(devConfig); Set dependenciesIndexSet = super.getDependenciesIndexSet(); for (Dependency dependency : moduleDependencies.values()) { dependenciesIndexSet.add(dependency.getClassesPath()); } + List localJars = devConfig.getLocalJars(); + if(!ObjectUtils.isEmpty(localJars)){ + dependenciesIndexSet.addAll(localJars); + } return dependenciesIndexSet; } 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 3e24c97..4d1e3ee 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 @@ -31,6 +31,7 @@ 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,11 +87,7 @@ public class JarOuterPackager extends JarNestPackager { attributes.putValue(START_CLASS, mainConfig.getMainClass()); attributes.putValue(MAIN_CLASS, MAIN_CLASS_VALUE); attributes.putValue(MAIN_PACKAGE_TYPE, PackageType.MAIN_PACKAGE_TYPE_JAR_OUTER); - String libDir = PackageStructure.LIB_NAME; - if(!ObjectUtils.isEmpty(mainConfig.getLibDir())){ - libDir = mainConfig.getLibDir(); - } - attributes.putValue(MAIN_LIB_DIR, libDir); + attributes.putValue(MAIN_LIB_DIR, getLibPath()); attributes.putValue(MAIN_LIB_INDEXES, getLibIndexes()); return manifest; } @@ -119,12 +116,25 @@ public class JarOuterPackager extends JarNestPackager { packageJar.copyZipToPackage(artifact.getFile()); } else { File artifactFile = artifact.getFile(); - String targetFilePath = FilesUtils.joiningFilePath( - mainConfig.getOutputDirectory(), PackageStructure.LIB_NAME, artifactFile.getName()); + String libPath = getLibPath(); + if(FilesUtils.isRelativePath(libPath)){ + libPath = FilesUtils.resolveRelativePath(mainConfig.getOutputDirectory(), getLibPath()); + } else { + libPath = FilesUtils.joiningFilePath(mainConfig.getOutputDirectory(), libPath); + } + String targetFilePath = FilesUtils.joiningFilePath(libPath, artifactFile.getName()); FileUtils.copyFile(artifactFile, new File(targetFilePath)); dependencyIndexNames.add(artifactFile.getName()); } } } + private String getLibPath(){ + String libDir = PackageStructure.LIB_NAME; + if(!ObjectUtils.isEmpty(mainConfig.getLibDir())){ + libDir = mainConfig.getLibDir(); + } + return libDir; + } + } 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 ebe06e7..ddfb1ce 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 @@ -1,21 +1,17 @@ - - Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.2 + 3.0.3 spring-brick-packager false true repackage - Repackage existing JAR and WAR archives so that they can be executed from the command - line using {@literal java -jar}. With <code>layout=NONE</code> can also be used simply - to package a JAR with nested dependencies (and no main class, so not executable). + 重新打包 compile+runtime false true @@ -28,54 +24,49 @@ java per-lookup once-per-session - 1.0.0 + 3.0.0 compile+runtime true project org.apache.maven.project.MavenProject - 1.0.0 + 3.0.0 true false - The Maven project. + 当前项目 outputDirectory java.io.File - 1.0.0 + 3.0.0 true true - Directory containing the generated archive. + 打包输出目录地址 includes java.util.List - 1.2.0 + 3.0.0 false true - Collection of artifact definitions to include. The {@link Include} element defines - mandatory {@code groupId} and {@code artifactId} properties and an optional - mandatory {@code groupId} and {@code artifactId} properties and an optional - {@code classifier} property. + 包含依赖定义 excludes java.util.List - 1.1.0 + 3.0.0 false true - Collection of artifact definitions to exclude. The {@link Exclude} element defines - mandatory {@code groupId} and {@code artifactId} properties and an optional - {@code classifier} property. + 排除依赖定义 skip boolean - 1.2.0 + 3.0.0 false true - Skip the execution. + 跳过执行 mode 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 ebe06e7..ddfb1ce 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 @@ -1,21 +1,17 @@ - - Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.2 + 3.0.3 spring-brick-packager false true repackage - Repackage existing JAR and WAR archives so that they can be executed from the command - line using {@literal java -jar}. With <code>layout=NONE</code> can also be used simply - to package a JAR with nested dependencies (and no main class, so not executable). + 重新打包 compile+runtime false true @@ -28,54 +24,49 @@ java per-lookup once-per-session - 1.0.0 + 3.0.0 compile+runtime true project org.apache.maven.project.MavenProject - 1.0.0 + 3.0.0 true false - The Maven project. + 当前项目 outputDirectory java.io.File - 1.0.0 + 3.0.0 true true - Directory containing the generated archive. + 打包输出目录地址 includes java.util.List - 1.2.0 + 3.0.0 false true - Collection of artifact definitions to include. The {@link Include} element defines - mandatory {@code groupId} and {@code artifactId} properties and an optional - mandatory {@code groupId} and {@code artifactId} properties and an optional - {@code classifier} property. + 包含依赖定义 excludes java.util.List - 1.1.0 + 3.0.0 false true - Collection of artifact definitions to exclude. The {@link Exclude} element defines - mandatory {@code groupId} and {@code artifactId} properties and an optional - {@code classifier} property. + 排除依赖定义 skip boolean - 1.2.0 + 3.0.0 false true - Skip the execution. + 跳过执行 mode diff --git a/spring-brick/pom.xml b/spring-brick/pom.xml index e0c702d..c92fc86 100644 --- a/spring-brick/pom.xml +++ b/spring-brick/pom.xml @@ -7,7 +7,7 @@ spring-brick-parent com.gitee.starblues - 3.0.2 + 3.0.3 spring-brick 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 f5824ac..ac678a2 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,11 +49,11 @@ import java.util.stream.Collectors; /** * 抽象的插件管理者 * @author starBlues - * @version 3.0.2 + * @version 3.0.3 */ public class DefaultPluginManager implements PluginManager{ - private final Logger log = LoggerFactory.getLogger(this.getClass()); + private final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class); private final RealizeProvider provider; private final IntegrationConfiguration configuration; 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 d9b9b90..de3cd39 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 @@ -60,7 +60,8 @@ public class PluginLauncherManager extends DefaultPluginManager{ GenericApplicationContext applicationContext, IntegrationConfiguration configuration) { super(realizeProvider, configuration); - this.mainApplicationContext = new MainApplicationContextProxy(applicationContext, applicationContext); + this.mainApplicationContext = + new MainApplicationContextProxy(applicationContext, configuration, applicationContext); this.mainGenericApplicationContext = applicationContext; this.configuration = configuration; this.invokeSupperCache = new DefaultInvokeSupperCache(); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java index 8772b54..8da8b8c 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java @@ -99,8 +99,13 @@ public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDef patterns.add("org/springframework/remoting/**"); patterns.add("org/springframework/ui/**"); - patterns.add("com/fasterxml/jackson/**"); + patterns.add("org/springframework/boot/autoconfigure/http/**"); + patterns.add("org/springframework/boot/autoconfigure/web/**"); + patterns.add("org/springframework/boot/autoconfigure/websocket/**"); + patterns.add("org/springframework/boot/autoconfigure/webservices/**"); + patterns.add("org/springframework/boot/autoconfigure/jackson/**"); + patterns.add("com/fasterxml/jackson/**"); } protected void addApiDoc(Set patterns){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java index 5134ad9..39e3af8 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java @@ -32,7 +32,7 @@ import java.util.Set; /** * 自动集成的配置 * @author starBlues - * @version 3.0.1 + * @version 3.0.3 */ @EqualsAndHashCode(callSuper = true) @Component @@ -92,7 +92,7 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio * pluginRestPathPrefix: 为pluginRestPathPrefix的配置值 * pluginId: 为插件id */ - @Value("${pluginRestPathPrefix:true}") + @Value("${enablePluginIdRestPathPrefix:true}") private Boolean enablePluginIdRestPathPrefix; /** diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointWebConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointWebConfiguration.java index e1e197d..9c198e3 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointWebConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointWebConfiguration.java @@ -17,6 +17,7 @@ package com.gitee.starblues.integration; import com.gitee.starblues.integration.listener.SwaggerListener; +import com.gitee.starblues.spring.ResolvePluginThreadClassLoader; import com.gitee.starblues.spring.web.PluginStaticResourceConfig; import com.gitee.starblues.spring.web.PluginStaticResourceWebMvcConfigurer; import com.gitee.starblues.spring.web.thymeleaf.PluginThymeleafInvolved; @@ -27,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.resource.ResourceResolver; import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.templatemode.TemplateMode; @@ -90,4 +92,9 @@ public class ExtendPointWebConfiguration { } + @Bean + public WebMvcConfigurer webMvcConfigurer(){ + return new ResolvePluginThreadClassLoader(); + } + } 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 d7017a0..24b2df3 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 @@ -32,4 +32,19 @@ public interface MainApplicationContext extends ApplicationContext { */ Map> getConfigurableEnvironment(); + /** + * If Resolve the specified main dependency against the beans defined in this factory. + * + * @param packageName 当前依赖包名称 + * @return boolean + */ + boolean isResolveDependency(String packageName); + + /** + * 是否为web环境 + * @return boolean + */ + boolean isWebEnvironment(); + + } 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 b77d4a3..27e5f25 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,6 +16,9 @@ package com.gitee.starblues.spring; +import com.gitee.starblues.integration.IntegrationConfiguration; +import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; @@ -34,15 +37,24 @@ 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) { + public MainApplicationContextProxy(GenericApplicationContext applicationContext, + IntegrationConfiguration configuration) { super(applicationContext.getBeanFactory()); this.applicationContext = applicationContext; + this.configuration = configuration; + this.isWebEnvironment = getIsWebEnvironment(applicationContext); } - public MainApplicationContextProxy(GenericApplicationContext applicationContext, AutoCloseable autoCloseable) { + public MainApplicationContextProxy(GenericApplicationContext applicationContext, + IntegrationConfiguration configuration, + AutoCloseable autoCloseable) { super(applicationContext.getBeanFactory(), autoCloseable); this.applicationContext = applicationContext; + this.configuration = configuration; + this.isWebEnvironment = getIsWebEnvironment(applicationContext); } @Override @@ -67,4 +79,19 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme return environmentMap; } + @Override + public boolean isResolveDependency(String packageName) { + return packageName.startsWith(configuration.mainPackage()); + } + + @Override + public boolean isWebEnvironment() { + return isWebEnvironment; + } + + private boolean getIsWebEnvironment(GenericApplicationContext applicationContext){ + return applicationContext instanceof AnnotationConfigServletWebServerApplicationContext + || applicationContext instanceof AnnotationConfigReactiveWebServerApplicationContext; + } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/ResolvePluginThreadClassLoader.java b/spring-brick/src/main/java/com/gitee/starblues/spring/ResolvePluginThreadClassLoader.java new file mode 100644 index 0000000..f2191e9 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/ResolvePluginThreadClassLoader.java @@ -0,0 +1,71 @@ +/** + * 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; + +import com.gitee.starblues.loader.classloader.GenericClassLoader; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 解决插件线程中的ClassLoader + * + * @author starBlues + * @version 3.0.3 + */ +public class ResolvePluginThreadClassLoader implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new ResolveHandlerInterceptor()).addPathPatterns("/**"); + } + + private static class ResolveHandlerInterceptor implements HandlerInterceptor { + + private final ThreadLocal oldClassLoader = new ThreadLocal<>(); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if(handler instanceof HandlerMethod){ + HandlerMethod handlerMethod = (HandlerMethod) handler; + ClassLoader classLoader = handlerMethod.getBeanType().getClassLoader(); + if(classLoader instanceof GenericClassLoader){ + oldClassLoader.set(Thread.currentThread().getContextClassLoader()); + Thread.currentThread().setContextClassLoader(classLoader); + } + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + try { + ClassLoader classLoader = oldClassLoader.get(); + if(classLoader != null){ + Thread.currentThread().setContextClassLoader(classLoader); + } + } finally { + oldClassLoader.remove(); + } + } + } + +} diff --git a/update.md b/update.md index f2ee7f5..7e7d884 100644 --- a/update.md +++ b/update.md @@ -1,7 +1,9 @@ -1. 新增 `xx-outer、dir` 打包类型的插件可自定义依赖目录 -2. 新增`includeSystemScope`、`type=main` 打包属性 -3. 修复插件拦截器无法拦截不存在的url -4. 修复主程序在 `jar-outer` 打包模式后无法启动问题 -5. 修复插件首次安装时异常 -6. fix https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I53K4G -7. fix https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I53T9W \ No newline at end of file +1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 +插件可触发`WebServerInitializedEvent`类型的事件 +2. 【支持】支持插件`Controller`可不配置地址前缀 +3. 【修复】`enablePluginIdRestPathPrefix`不生效问题 +4. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` +5. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 +插件`Controller`使用`Aop`后, 获取不到参数 +6. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 +主程序打包参数`libDir`不生效问题 \ No newline at end of file -- Gitee From 8bea878752988d156e7acacf466b4c76db63b4a1 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 22 May 2022 18:01:15 +0800 Subject: [PATCH 02/11] fix debug --- .../PluginMainResourcePatternDefiner.java | 9 +++++++-- .../web/PluginStaticResourceResolver.java | 20 ++++++++++++++++--- update.md | 15 ++++++++------ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java index 8da8b8c..e74dfce 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java @@ -61,6 +61,8 @@ public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDef addApiDoc(includeResourcePatterns); addDbDriver(includeResourcePatterns); + addIdea(includeResourcePatterns); + // 配置插件自定义从主程序加载的资源匹配 Set includeMainResourcePatterns = descriptor.getIncludeMainResourcePatterns(); if(ObjectUtils.isEmpty(includeMainResourcePatterns)){ @@ -76,8 +78,6 @@ public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDef return includeResourcePatterns; } - - @Override public Set getExcludePatterns() { Set excludeResourcePatterns = new HashSet<>(); @@ -141,6 +141,11 @@ public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDef patterns.add("jdbc/h2/**"); } + private void addIdea(Set includeResourcePatterns) { + // idea debug agent + includeResourcePatterns.add("com/intellij/rt/debugger/agent/**"); + } + /** * 获取基本的 MainResourcePatternDefiner * @param pluginInteractive PluginInteractive 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 b923cde..4e6c89a 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 @@ -106,8 +106,18 @@ public class PluginStaticResourceResolver extends AbstractResourceResolver { // 存在后缀 return null; } - partialPath = UrlUtils.joiningUrlPath(partialPath, indexPageName); - return findResource(pluginResource, partialPath); + + // 查找第一级节点,找不到则读取根index.html + if(partialPath.contains(UrlUtils.SPLIT)){ + partialPath = partialPath.substring(0, partialPath.indexOf(UrlUtils.SPLIT)); + } + // 第一级节点 + resource = findResource(pluginResource, UrlUtils.joiningUrlPath(partialPath, indexPageName)); + if(resource != null){ + return resource; + } + // 根节点 + return findResource(pluginResource, UrlUtils.joiningUrlPath(UrlUtils.SPLIT, indexPageName)); } } @@ -144,7 +154,11 @@ public class PluginStaticResourceResolver extends AbstractResourceResolver { PluginResource resource = new PluginResource(classPath + partialPath, pluginResource.getPluginDescriptor()); resource.setClassLoader(pluginClassLoader); if(resource.exists()){ - return resource; + // 确保资源为文件 + File file = resource.getFile(); + if(file != null && file.isFile()){ + return resource; + } } } catch (Exception e){ logger.debug("Get static resources of classpath '{}' error.", classPath, e); diff --git a/update.md b/update.md index 7e7d884..06ba901 100644 --- a/update.md +++ b/update.md @@ -1,9 +1,12 @@ 1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 插件可触发`WebServerInitializedEvent`类型的事件 -2. 【支持】支持插件`Controller`可不配置地址前缀 -3. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -4. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -5. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 +2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) +3. 【支持】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) +4. 【修复】`enablePluginIdRestPathPrefix`不生效问题 +5. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` +6. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 -6. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 -主程序打包参数`libDir`不生效问题 \ No newline at end of file +7. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 +主程序打包参数`libDir`不生效问题 +8. 【优化】优化静态资源文件加载问题 +9. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` \ No newline at end of file -- Gitee From 51db24fbf3d3f5cb2e7676dde64b7a10f335d538 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sat, 28 May 2022 13:12:06 +0800 Subject: [PATCH 03/11] update to 3.0.3 --- .../bootstrap/ConfigurePluginEnvironment.java | 1 + .../EmptyMainApplicationContext.java | 4 +- .../bootstrap/PluginListableBeanFactory.java | 106 +++++++----- .../bootstrap/PluginSpringApplication.java | 2 +- .../bootstrap/annotation/AutowiredType.java | 46 ++++++ .../plugin/pack/AbstractPackagerMojo.java | 3 + .../plugin/pack/BasicRepackager.java | 3 +- .../gitee/starblues/plugin/pack/Constant.java | 8 +- .../starblues/plugin/pack/RepackageMojo.java | 1 - .../plugin/pack/main/JarOuterPackager.java | 4 +- .../plugin/pack/prod/DirProdRepackager.java | 13 +- .../plugin/pack/prod/ProdRepackager.java | 1 - .../plugin/pack/prod/ZipProdRepackager.java | 1 + .../plugin/pack/utils/CommonUtils.java | 22 +++ .../plugin/pack/utils/PackageJar.java | 3 +- .../plugin/pack/utils/PackageZip.java | 16 +- .../checker/DefaultPluginLauncherChecker.java | 7 +- .../classloader/CacheMainResourceMatcher.java | 4 +- .../ComposeMainResourceMatcher.java | 62 +++++++ .../DefaultMainResourceMatcher.java | 32 ++-- .../core/classloader/MainResourceMatcher.java | 4 +- .../core/classloader/PluginClassLoader.java | 19 +-- .../ProhibitMainResourceMatcher.java | 4 +- .../DefaultMainResourcePatternDefiner.java | 153 ++++++++++++++++++ .../core/launcher/plugin/PluginLauncher.java | 29 +++- .../PluginMainResourcePatternDefiner.java | 117 +------------- .../DefaultIntegrationConfiguration.java | 3 +- .../integration/ExtendPointConfiguration.java | 14 +- .../spring/MainApplicationContext.java | 7 +- .../spring/MainApplicationContextProxy.java | 12 +- update.md | 21 +-- 31 files changed, 482 insertions(+), 240 deletions(-) create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java create mode 100644 spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java create mode 100644 spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultMainResourcePatternDefiner.java 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 c159c6e..67ba594 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 @@ -23,6 +23,7 @@ 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.springframework.context.support.LiveBeansView; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; 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 e4ddb24..34c6c9c 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 @@ -47,8 +47,8 @@ public class EmptyMainApplicationContext implements MainApplicationContext { } @Override - public boolean isResolveDependency(String packageName) { - return false; + public Object resolveDependency(String requestingBeanName, Class dependencyType) { + return null; } @Override 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 5d1a873..3aef325 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 @@ -16,24 +16,24 @@ package com.gitee.starblues.bootstrap; +import com.gitee.starblues.bootstrap.annotation.AutowiredType; +import com.gitee.starblues.bootstrap.processor.ProcessorContext; import com.gitee.starblues.bootstrap.utils.DestroyUtils; +import com.gitee.starblues.core.classloader.MainResourceMatcher; +import com.gitee.starblues.core.classloader.PluginClassLoader; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; -import com.gitee.starblues.utils.ObjectUtils; import com.gitee.starblues.utils.ReflectionUtils; import lombok.AllArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; -import org.springframework.beans.factory.BeanFactory; 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.core.ResolvableType; import org.springframework.lang.Nullable; import java.util.Map; @@ -49,12 +49,14 @@ import java.util.stream.Stream; */ public class PluginListableBeanFactory extends DefaultListableBeanFactory { - private final Logger logger = LoggerFactory.getLogger(PluginListableBeanFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(PluginListableBeanFactory.class); private final MainApplicationContext applicationContext; + private final ClassLoader pluginClassLoader; - public PluginListableBeanFactory(MainApplicationContext applicationContext) { - this.applicationContext = applicationContext; + public PluginListableBeanFactory(ProcessorContext processorContext) { + this.applicationContext = processorContext.getMainApplicationContext(); + this.pluginClassLoader = processorContext.getResourceLoader().getClassLoader(); } @SuppressWarnings("unchecked") @@ -64,25 +66,45 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { if(isDisabled(descriptor)){ - return resolveDependencyFromMain(descriptor, false); + // 插件被禁用的依赖Bean直接从主程序获取。 + return resolveDependencyFromMain(requestingBeanName, descriptor); } - try { - Object object = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, - typeConverter); - - if(object instanceof ObjectProvider){ - return new PluginObjectProviderWrapper((ObjectProvider) object, descriptor); + AutowiredType.Type autowiredType = getAutowiredType(descriptor); + if(autowiredType == AutowiredType.Type.MAIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; } - return object; - } catch (BeansException e){ - if(e instanceof NoSuchBeanDefinitionException){ - Object dependencyBean = resolveDependencyFromMain(descriptor, true); - if(dependencyBean != null){ - return dependencyBean; + throw new NoSuchBeanDefinitionException(descriptor.getDependencyType()); + } else if(autowiredType == AutowiredType.Type.PLUGIN){ + return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ + try { + Object object = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + typeConverter); + + if(object instanceof ObjectProvider){ + return new PluginObjectProviderWrapper((ObjectProvider) object, requestingBeanName, descriptor); } + return object; + } catch (BeansException e){ + if(e instanceof NoSuchBeanDefinitionException){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + } + throw e; + } + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; } - throw e; + return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + typeConverter); } + throw new NoSuchBeanDefinitionException(descriptor.getDependencyType()); } @Override @@ -100,23 +122,33 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { return super.getBeanProvider(requiredType, allowEagerInit); } - - private Object resolveDependencyFromMain(DependencyDescriptor descriptor, boolean isResolveDependency){ - String packageName = descriptor.getDependencyType().getPackage().getName(); - if(isResolveDependency && !applicationContext.isResolveDependency(packageName)){ - return null; - } - String dependencyName = descriptor.getDependencyName(); - SpringBeanFactory springBeanFactory = applicationContext.getSpringBeanFactory(); - if(!ObjectUtils.isEmpty(dependencyName) && springBeanFactory.containsBean(dependencyName)){ - return springBeanFactory.getBean(dependencyName); + private AutowiredType.Type getAutowiredType(DependencyDescriptor descriptor){ + AutowiredType autowiredType = descriptor.getAnnotation(AutowiredType.class); + if(autowiredType != null){ + return autowiredType.value(); } else { - try { - return springBeanFactory.getBean(descriptor.getDependencyType()); - } catch (Exception e){ - throw new NoSuchBeanDefinitionException(descriptor.getDependencyType()); + return AutowiredType.Type.PLUGIN_MAIN; + } + } + + private 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"); } + } catch (Exception e){ + return null; } + return dependencyObj; } private void destroyAll(){ @@ -141,12 +173,14 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { private class PluginObjectProviderWrapper implements ObjectProvider { private final ObjectProvider pluginObjectProvider; + + private final String requestingBeanName; private final DependencyDescriptor descriptor; @Override public Object getObject() throws BeansException { if(isDisabled(descriptor)){ - return resolveDependencyFromMain(descriptor, false); + return resolveDependencyFromMain(requestingBeanName, descriptor); } return pluginObjectProvider.getObject(); } 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 8ac00e9..abdb79f 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 @@ -59,7 +59,7 @@ public class PluginSpringApplication extends SpringApplication { this.pluginProcessor = pluginProcessor; this.processorContext = processorContext; this.resourceLoader = processorContext.getResourceLoader(); - this.beanFactory = new PluginListableBeanFactory(processorContext.getMainApplicationContext()); + this.beanFactory = new PluginListableBeanFactory(processorContext); this.configurePluginEnvironment = new ConfigurePluginEnvironment(processorContext); this.applicationContext = getApplicationContext(); setDefaultPluginConfig(); 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 new file mode 100644 index 0000000..af34b00 --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java @@ -0,0 +1,46 @@ +package com.gitee.starblues.bootstrap.annotation; + + +import java.lang.annotation.*; + +/** + * 注入类型 + * + * @author starBlues + * @version 3.0.3 + */ +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AutowiredType { + + /** + * 插件Bean注入类型 + * @return Type + */ + Type value() default Type.PLUGIN_MAIN; + + enum Type{ + /** + * Bean 注入类型(默认): 先插件后主程序 + */ + PLUGIN_MAIN, + + /** + * Bean 注入类型: 先主程序后插件 + */ + MAIN_PLUGIN, + + /** + * Bean 注入类型: 仅插件 + */ + PLUGIN, + + /** + * Bean 注入类型: 仅主程序 + */ + MAIN + } + + +} diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java index b24c525..bfd4037 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java @@ -48,6 +48,9 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo{ @Parameter(property = "spring-brick-packager.skip", defaultValue = "false") private boolean skip; + @Parameter + private String classifier; + @Parameter(property = "spring-brick-packager.pluginInfo") private PluginInfo pluginInfo; diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java index 44bc3a5..7eee475 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java @@ -17,6 +17,7 @@ package com.gitee.starblues.plugin.pack; import com.gitee.starblues.common.*; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.ObjectUtils; import lombok.Getter; @@ -120,7 +121,7 @@ public class BasicRepackager implements Repackager{ protected String createRootDir() throws MojoFailureException { String rootDirPath = getBasicRootDir(); File rootDir = new File(rootDirPath); - rootDir.deleteOnExit(); + CommonUtils.deleteFile(rootDir); if(rootDir.mkdir()){ return rootDirPath; } 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 a08d41b..b66fe5d 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 @@ -31,6 +31,8 @@ public class Constant { public static final String SCOPE_SYSTEM = "system"; public static final String SCOPE_TEST = "test"; + public static final String MAVEN_POM_TYPE = "pom"; + public static final String MAVEN_MAIN_TYPE = "main"; public static final String MODE_MAIN = "main"; @@ -51,7 +53,7 @@ public class Constant { if(Constant.isSystemScope(artifact.getScope())){ return includeSystemScope == null || !includeSystemScope; } - return false; + return Constant.filterPomTypeArtifact(artifact); } public static boolean filterMainTypeArtifact(Artifact artifact){ @@ -59,6 +61,10 @@ public class Constant { return MAVEN_MAIN_TYPE.equalsIgnoreCase(artifact.getType()); } + public static boolean filterPomTypeArtifact(Artifact artifact){ + return MAVEN_POM_TYPE.equalsIgnoreCase(artifact.getType()); + } + public static boolean scopeFilter(String scope){ return SCOPE_PROVIDED.equalsIgnoreCase(scope) || SCOPE_TEST.equalsIgnoreCase(scope); diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java index 0e6dbb7..1aa220a 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java @@ -34,7 +34,6 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; 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 4d1e3ee..de5a493 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 @@ -69,9 +69,7 @@ public class JarOuterPackager extends JarNestPackager { String fileName = mainConfig.getFileName(); String rootDirPath = FilesUtils.joiningFilePath(outputDirectory, fileName); File rootFile = new File(rootDirPath); - if(rootFile.exists()){ - rootFile.deleteOnExit(); - } + CommonUtils.deleteFile(rootFile); if(rootFile.mkdirs()){ return rootDirPath; } else { diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java index 5a3bd8e..bd819f6 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java @@ -68,18 +68,7 @@ public class DirProdRepackager extends DevRepackager { String fileName = prodConfig.getFileName(); String dirPath = FilesUtils.joiningFilePath(prodConfig.getOutputDirectory(), fileName); File dirFile = new File(dirPath); - if(dirFile.exists() && dirFile.isFile()){ - int i = 0; - while (true){ - dirFile = new File(dirPath + "_" + i); - if(dirFile.exists() && dirFile.isFile()){ - i = i + 1; - continue; - } - break; - } - } - dirFile.deleteOnExit(); + CommonUtils.deleteFile(dirFile); if(!dirFile.mkdirs()){ throw new MojoFailureException("Create package dir failure: " + dirFile.getPath()); } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java index 9db3b18..0ff7d34 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java @@ -17,7 +17,6 @@ package com.gitee.starblues.plugin.pack.prod; import com.gitee.starblues.common.PackageType; -import com.gitee.starblues.plugin.pack.Constant; import com.gitee.starblues.plugin.pack.PluginInfo; import com.gitee.starblues.plugin.pack.RepackageMojo; import com.gitee.starblues.plugin.pack.Repackager; 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 dacd996..303fd54 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 @@ -25,6 +25,7 @@ import com.gitee.starblues.plugin.pack.RepackageMojo; import com.gitee.starblues.plugin.pack.dev.Dependency; import com.gitee.starblues.plugin.pack.dev.DevConfig; import com.gitee.starblues.plugin.pack.dev.DevRepackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; import com.gitee.starblues.plugin.pack.utils.PackageZip; import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.ObjectUtils; diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java index 87b282e..09ac0a0 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java @@ -17,8 +17,11 @@ package com.gitee.starblues.plugin.pack.utils; import com.gitee.starblues.plugin.pack.filter.Exclude; +import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoFailureException; +import java.io.File; import java.util.Objects; /** @@ -48,4 +51,23 @@ public class CommonUtils { return Objects.equals(artifact.getGroupId(), PLUGIN_FRAMEWORK_GROUP_ID) && Objects.equals(artifact.getArtifactId(), PLUGIN_FRAMEWORK_LOADER_ARTIFACT_ID); } + + public static void deleteFile(File rootFile) throws MojoFailureException { + try { + if(rootFile == null){ + return; + } + if(!rootFile.exists()){ + return; + } + if(rootFile.isFile()){ + FileUtils.delete(rootFile); + } else { + FileUtils.deleteDirectory(rootFile); + } + } catch (Exception e){ + e.printStackTrace(); + throw new MojoFailureException("Delete file '" + rootFile.getPath() + "' failure. " + e.getMessage()); + } + } } diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java index d82a8f3..cf30122 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java @@ -23,6 +23,7 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import java.io.File; import java.io.FileOutputStream; +import java.nio.file.Files; /** * jar 打包工具 @@ -45,7 +46,7 @@ public class PackageJar extends PackageZip{ @Override protected ArchiveOutputStream getOutputStream(File packFile) throws Exception { - return new JarArchiveOutputStream(new FileOutputStream(packFile)); + return new JarArchiveOutputStream(Files.newOutputStream(packFile.toPath())); } @Override diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java index 7867941..f7aa974 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java @@ -28,6 +28,7 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import java.io.*; +import java.nio.file.Files; import java.util.Enumeration; import java.util.jar.Manifest; import java.util.zip.CRC32; @@ -73,18 +74,7 @@ public class PackageZip implements Closeable{ protected File getPackageFile(String rootPath) throws Exception { String fileSuffix = getPackageFileSuffix(); File file = new File(rootPath + "." + fileSuffix); - - if(file.exists()){ - int i = 0; - while (true){ - file = new File(rootPath + "_" + i + "." + fileSuffix); - if(file.exists()){ - i = i + 1; - continue; - } - break; - } - } + CommonUtils.deleteFile(file); if(file.createNewFile()){ return file; } @@ -96,7 +86,7 @@ public class PackageZip implements Closeable{ } protected ArchiveOutputStream getOutputStream(File packFile) throws Exception { - return new ZipArchiveOutputStream(new FileOutputStream(packFile)); + return new ZipArchiveOutputStream(Files.newOutputStream(packFile.toPath())); } public void copyDirToPackage(File rootDir, String packageDir) throws Exception { diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java b/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java index 052b74a..f2590e5 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java @@ -77,6 +77,9 @@ public class DefaultPluginLauncherChecker implements PluginLauncherChecker { return; } String requires = pluginInfo.getPluginDescriptor().getRequires(); + if(ObjectUtils.isEmpty(requires)){ + return; + } boolean exactVersion = configuration.exactVersion(); int compareVersion = realizeProvider.getVersionInspector().compareTo(requires, version); PluginDescriptor descriptor = pluginInfo.getPluginDescriptor(); @@ -92,8 +95,4 @@ public class DefaultPluginLauncherChecker implements PluginLauncherChecker { } } - - - - } 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 58ed42a..ff90653 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,7 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * 可缓存的 ResourceMatcher * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class CacheMainResourceMatcher extends DefaultMainResourceMatcher implements AutoCloseable { @@ -34,7 +34,7 @@ public class CacheMainResourceMatcher extends DefaultMainResourceMatcher impleme } @Override - public boolean match(String resourceUrl) { + public Boolean match(String resourceUrl) { Boolean match = resourceUrlMatchCache.get(resourceUrl); if(match == null){ match = super.match(resourceUrl); 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 new file mode 100644 index 0000000..c993535 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ComposeMainResourceMatcher.java @@ -0,0 +1,62 @@ +/** + * 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.utils.ObjectUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 组合的 MainResourcePatternDefiner + * + * @author starBlues + * @version 3.0.3 + */ +public class ComposeMainResourceMatcher implements MainResourceMatcher{ + + private final List resourceMatchers; + + public ComposeMainResourceMatcher(){ + this(null); + } + + public ComposeMainResourceMatcher(List resourceMatchers) { + if(ObjectUtils.isEmpty(resourceMatchers)){ + this.resourceMatchers = new ArrayList<>(); + } else { + this.resourceMatchers = resourceMatchers; + } + } + + public void addMainResourceMatcher(MainResourceMatcher mainResourceMatcher){ + if(mainResourceMatcher == null){ + return; + } + resourceMatchers.add(mainResourceMatcher); + } + + @Override + public Boolean match(String resourceUrl) { + for (MainResourceMatcher resourceMatcher : resourceMatchers) { + if(resourceMatcher.match(resourceUrl)){ + return Boolean.TRUE; + } + } + return Boolean.FALSE; + } +} 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 29c95de..8c82daa 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 @@ -30,6 +30,11 @@ import java.util.Set; */ 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; @@ -42,13 +47,13 @@ public class DefaultMainResourceMatcher implements MainResourceMatcher{ } @Override - public boolean match(String resourceUrl) { + public Boolean match(String resourceUrl) { return match(includePatterns, resourceUrl); } - private boolean match(Collection patterns, String url){ + private Boolean match(Collection patterns, String url){ if(ObjectUtils.isEmpty(patterns) || ObjectUtils.isEmpty(url)){ - return false; + return Boolean.FALSE; } url = formatUrl(url); for (String pattern : patterns) { @@ -57,28 +62,33 @@ public class DefaultMainResourceMatcher implements MainResourceMatcher{ return !excludeMatch(excludePatterns, url); } } - return false; + return Boolean.FALSE; } - private boolean excludeMatch(Collection patterns, String url){ + private Boolean excludeMatch(Collection patterns, String url){ if(ObjectUtils.isEmpty(patterns) || ObjectUtils.isEmpty(url)){ - return false; + return Boolean.FALSE; } url = formatUrl(url); for (String pattern : patterns) { boolean match = pathMatcher.match(pattern, url); if(match){ - return true; + return Boolean.TRUE; } } - return false; + return Boolean.FALSE; } private String formatUrl(String url){ - url = url.replace("\\", AntPathMatcher.DEFAULT_PATH_SEPARATOR); - if(url.startsWith(AntPathMatcher.DEFAULT_PATH_SEPARATOR)){ - url = url.substring(url.indexOf(AntPathMatcher.DEFAULT_PATH_SEPARATOR) + 1); + 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/MainResourceMatcher.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourceMatcher.java index 5977f35..9b94955 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourceMatcher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/MainResourceMatcher.java @@ -19,7 +19,7 @@ package com.gitee.starblues.core.classloader; /** * 主程序资源匹配者 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public interface MainResourceMatcher { @@ -28,6 +28,6 @@ public interface MainResourceMatcher { * @param resourceUrl 主程序资源url * @return true 匹配成功, false 匹配失败 */ - boolean match(String resourceUrl); + Boolean match(String resourceUrl); } 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 31f624f..c94681e 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 @@ -38,27 +38,24 @@ import java.util.Set; /** * 插件 classLoader * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ @Slf4j public class PluginClassLoader extends GenericClassLoader { private final GenericClassLoader parentClassLoader; - private MainResourceMatcher mainResourceMatcher; + private final MainResourceMatcher mainResourceMatcher; - public PluginClassLoader(String name, GenericClassLoader parentClassLoader, MainResourcePatternDefiner patternDefiner, - ResourceLoaderFactory resourceLoaderFactory) { + public PluginClassLoader(String name, GenericClassLoader parentClassLoader, + ResourceLoaderFactory resourceLoaderFactory, + MainResourceMatcher mainResourceMatcher) { super(name, parentClassLoader, resourceLoaderFactory); this.parentClassLoader = parentClassLoader; - if(patternDefiner != null){ - setMainResourceMatcher(new CacheMainResourceMatcher(patternDefiner)); - } else { - setMainResourceMatcher(new ProhibitMainResourceMatcher()); - } + this.mainResourceMatcher = mainResourceMatcher; } - public void setMainResourceMatcher(MainResourceMatcher mainResourceMatcher){ - this.mainResourceMatcher = Assert.isNotNull(mainResourceMatcher, "参数 mainResourceMatcher 不能为空"); + public MainResourceMatcher getMainResourceMatcher() { + return mainResourceMatcher; } public void addResource(InsidePluginDescriptor descriptor) throws Exception { diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ProhibitMainResourceMatcher.java b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ProhibitMainResourceMatcher.java index 296dacf..cba6d62 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ProhibitMainResourceMatcher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/classloader/ProhibitMainResourceMatcher.java @@ -19,12 +19,12 @@ package com.gitee.starblues.core.classloader; /** * 禁止匹配所有主程序资源 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ public class ProhibitMainResourceMatcher implements MainResourceMatcher{ @Override - public boolean match(String resourceUrl) { + public Boolean match(String resourceUrl) { return false; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultMainResourcePatternDefiner.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultMainResourcePatternDefiner.java new file mode 100644 index 0000000..ac6014e --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/DefaultMainResourcePatternDefiner.java @@ -0,0 +1,153 @@ +/** + * 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.launcher.plugin; + +import com.gitee.starblues.core.classloader.MainResourcePatternDefiner; +import com.gitee.starblues.core.launcher.JavaMainResourcePatternDefiner; +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.SpringBeanUtils; +import org.springframework.context.ApplicationContext; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 主程序资源匹配定义 + * + * @author starBlues + * @version 3.0.3 + */ +public class DefaultMainResourcePatternDefiner extends JavaMainResourcePatternDefiner { + + private static final String FRAMEWORK = "com/gitee/starblues/**"; + + public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; + + private final String mainPackage; + private final ApplicationContext applicationContext; + + public DefaultMainResourcePatternDefiner(String mainPackage, ApplicationContext applicationContext) { + this.mainPackage = mainPackage; + this.applicationContext = applicationContext; + } + + @Override + public Set getIncludePatterns() { + Set includeResourcePatterns = super.getIncludePatterns(); + // add mainPackage + includeResourcePatterns.add(ObjectUtils.changePackageToMatch(mainPackage)); + // add framework + includeResourcePatterns.add(FRAMEWORK); + addWebIncludeResourcePatterns(includeResourcePatterns); + addApiDoc(includeResourcePatterns); + addDbDriver(includeResourcePatterns); + + addIdea(includeResourcePatterns); + + // add extension + List extensionPatternDefiners = getExtensionPatternDefiners(); + for (MainResourcePatternDefiner extensionPatternDefiner : extensionPatternDefiners) { + Set includePatterns = extensionPatternDefiner.getIncludePatterns(); + if(!ObjectUtils.isEmpty(includePatterns)){ + includeResourcePatterns.addAll(includePatterns); + } + } + + return includeResourcePatterns; + } + + @Override + public Set getExcludePatterns() { + Set excludeResourcePatterns = new HashSet<>(); + excludeResourcePatterns.add(FACTORIES_RESOURCE_LOCATION); + + // add extension + List extensionPatternDefiners = getExtensionPatternDefiners(); + for (MainResourcePatternDefiner extensionPatternDefiner : extensionPatternDefiners) { + Set excludePatterns = extensionPatternDefiner.getExcludePatterns(); + if(!ObjectUtils.isEmpty(excludePatterns)){ + excludeResourcePatterns.addAll(excludePatterns); + } + } + return excludeResourcePatterns; + } + + protected void addWebIncludeResourcePatterns(Set patterns) { + patterns.add("org/springframework/web/**"); + patterns.add("org/springframework/http/**"); + patterns.add("org/springframework/remoting/**"); + patterns.add("org/springframework/ui/**"); + + patterns.add("org/springframework/boot/autoconfigure/http/**"); + patterns.add("org/springframework/boot/autoconfigure/web/**"); + patterns.add("org/springframework/boot/autoconfigure/websocket/**"); + patterns.add("org/springframework/boot/autoconfigure/webservices/**"); + patterns.add("org/springframework/boot/autoconfigure/jackson/**"); + + patterns.add("com/fasterxml/jackson/**"); + } + + protected void addApiDoc(Set patterns) { + patterns.add("springfox/documentation/**"); + patterns.add("io/swagger/**"); + patterns.add("org/springdoc/**"); + } + + protected void addDbDriver(Set patterns) { + // mysql + patterns.add("com/mysql/**"); + // oracle + patterns.add("oracle/jdbc/**"); + // sqlserver + patterns.add("com/microsoft/jdbc/sqlserver/**"); + // DB2 + patterns.add("com/ibm/db2/jdbc/**"); + // DB2/AS400 + patterns.add("com/ibm/as400/**"); + // Informix + patterns.add("com/informix/jdbc/**"); + // Hypersonic + patterns.add("org/hsql/**"); + // MS SQL + patterns.add("com/microsoft/jdbc/**"); + // Postgres + patterns.add("org/postgresql/**"); + // Sybase + patterns.add("com/sybase/jdbc2/**"); + // Weblogic + patterns.add("weblogic/jdbc/**"); + // h2 + patterns.add("jdbc/h2/**"); + } + + private void addIdea(Set includeResourcePatterns) { + // idea debug agent + includeResourcePatterns.add("com/intellij/rt/debugger/agent/**"); + } + + + /** + * 获取扩展的 MainResourcePatternDefiner + * + * @return List + */ + private List getExtensionPatternDefiners() { + return SpringBeanUtils.getBeans(applicationContext, MainResourcePatternDefiner.class); + } + +} 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/PluginLauncher.java index 9878c3d..8ff0e50 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/PluginLauncher.java @@ -16,24 +16,28 @@ package com.gitee.starblues.core.launcher.plugin; +import com.gitee.starblues.core.classloader.*; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; -import com.gitee.starblues.core.classloader.PluginClassLoader; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; import com.gitee.starblues.loader.classloader.GenericClassLoader; import com.gitee.starblues.loader.classloader.resource.loader.DefaultResourceLoaderFactory; import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; import com.gitee.starblues.loader.launcher.AbstractLauncher; import com.gitee.starblues.loader.launcher.LauncherContext; +import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringPluginHook; import com.gitee.starblues.utils.MsgUtils; +import com.gitee.starblues.utils.SpringBeanCustomUtils; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.WeakHashMap; /** * 插件启动引导类 * @author starBlues - * @version 3.0.1 + * @version 3.0.3 */ public class PluginLauncher extends AbstractLauncher { @@ -41,7 +45,7 @@ public class PluginLauncher extends AbstractLauncher { protected final PluginInteractive pluginInteractive; protected final InsidePluginDescriptor pluginDescriptor; - protected final PluginMainResourcePatternDefiner mainResourcePatternDefiner; + protected final MainResourceMatcher mainResourceMatcher; protected final PluginLaunchInvolved pluginLaunchInvolved; @@ -49,10 +53,24 @@ public class PluginLauncher extends AbstractLauncher { PluginLaunchInvolved pluginLaunchInvolved) { this.pluginInteractive = pluginInteractive; this.pluginDescriptor = pluginInteractive.getPluginDescriptor(); - this.mainResourcePatternDefiner = new PluginMainResourcePatternDefiner(pluginInteractive); + this.mainResourceMatcher = getMainResourceMatcher(pluginInteractive); this.pluginLaunchInvolved = pluginLaunchInvolved; } + protected MainResourceMatcher getMainResourceMatcher(PluginInteractive pluginInteractive){ + MainApplicationContext mainApplicationContext = pluginInteractive.getMainApplicationContext(); + // 获取主程序定义的资源匹配 + List mainResourceMatchers = + SpringBeanCustomUtils.getBeans(mainApplicationContext, MainResourceMatcher.class); + + List resourceMatchers = new ArrayList<>(mainResourceMatchers); + // 新增插件定义的资源匹配 + resourceMatchers.add(new DefaultMainResourceMatcher( + new PluginMainResourcePatternDefiner(pluginInteractive) + )); + return new ComposeMainResourceMatcher(resourceMatchers); + } + @Override protected ClassLoader createClassLoader(String... args) throws Exception { PluginClassLoader pluginClassLoader = getPluginClassLoader(); @@ -68,8 +86,7 @@ public class PluginLauncher extends AbstractLauncher { return classLoader; } PluginClassLoader pluginClassLoader = new PluginClassLoader( - pluginId, getParentClassLoader(), mainResourcePatternDefiner, - getResourceLoaderFactory() + pluginId, getParentClassLoader(), getResourceLoaderFactory(), mainResourceMatcher ); CLASS_LOADER_CACHE.put(key, pluginClassLoader); return pluginClassLoader; diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java index e74dfce..f32c6b0 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginMainResourcePatternDefiner.java @@ -16,12 +16,9 @@ package com.gitee.starblues.core.launcher.plugin; +import com.gitee.starblues.core.classloader.MainResourcePatternDefiner; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; -import com.gitee.starblues.core.launcher.JavaMainResourcePatternDefiner; -import com.gitee.starblues.spring.MainApplicationContext; -import com.gitee.starblues.utils.Assert; import com.gitee.starblues.utils.ObjectUtils; -import com.gitee.starblues.utils.SpringBeanCustomUtils; import java.util.HashSet; import java.util.Set; @@ -29,51 +26,23 @@ import java.util.Set; /** * 定义插件从主程序加载资源的匹配 * @author starBlues - * @version 3.0.0 + * @version 3.0.3 */ -public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDefiner { +public class PluginMainResourcePatternDefiner implements MainResourcePatternDefiner { - private static final String FRAMEWORK = "com/gitee/starblues/**"; - - public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; - - private final String mainPackage; private final InsidePluginDescriptor descriptor; - private final BasicMainResourcePatternDefiner basicPatternDefiner; public PluginMainResourcePatternDefiner(PluginInteractive pluginInteractive) { - mainPackage = pluginInteractive.getConfiguration().mainPackage(); this.descriptor = pluginInteractive.getPluginDescriptor(); - basicPatternDefiner = getPatternDefiner(pluginInteractive); } @Override public Set getIncludePatterns() { - Set includeResourcePatterns = super.getIncludePatterns(); - Set includePatterns = basicPatternDefiner.getIncludePatterns(); - if(!ObjectUtils.isEmpty(includePatterns)){ - includeResourcePatterns.addAll(includePatterns); - } else { - includeResourcePatterns.add(ObjectUtils.changePackageToMatch(mainPackage)); - } - includeResourcePatterns.add(FRAMEWORK); - addWebIncludeResourcePatterns(includeResourcePatterns); - addApiDoc(includeResourcePatterns); - addDbDriver(includeResourcePatterns); - - addIdea(includeResourcePatterns); - + Set includeResourcePatterns = new HashSet<>(); // 配置插件自定义从主程序加载的资源匹配 Set includeMainResourcePatterns = descriptor.getIncludeMainResourcePatterns(); - if(ObjectUtils.isEmpty(includeMainResourcePatterns)){ - return includeResourcePatterns; - } - - for (String includeMainResourcePattern : includeMainResourcePatterns) { - if(ObjectUtils.isEmpty(includeMainResourcePattern)){ - continue; - } - includeResourcePatterns.add(includeMainResourcePattern); + if(!ObjectUtils.isEmpty(includeMainResourcePatterns)){ + includeResourcePatterns.addAll(includeMainResourcePatterns); } return includeResourcePatterns; } @@ -81,87 +50,13 @@ public class PluginMainResourcePatternDefiner extends JavaMainResourcePatternDef @Override public Set getExcludePatterns() { Set excludeResourcePatterns = new HashSet<>(); - Set excludePatterns = basicPatternDefiner.getExcludePatterns(); - if(!ObjectUtils.isEmpty(excludePatterns)){ - excludeResourcePatterns.addAll(excludePatterns); - } Set excludeMainResourcePatterns = descriptor.getExcludeMainResourcePatterns(); if(!ObjectUtils.isEmpty(excludeMainResourcePatterns)){ excludeResourcePatterns.addAll(excludeMainResourcePatterns); } - excludeResourcePatterns.add(FACTORIES_RESOURCE_LOCATION); return excludeResourcePatterns; } - protected void addWebIncludeResourcePatterns(Set patterns){ - patterns.add("org/springframework/web/**"); - patterns.add("org/springframework/http/**"); - patterns.add("org/springframework/remoting/**"); - patterns.add("org/springframework/ui/**"); - - patterns.add("org/springframework/boot/autoconfigure/http/**"); - patterns.add("org/springframework/boot/autoconfigure/web/**"); - patterns.add("org/springframework/boot/autoconfigure/websocket/**"); - patterns.add("org/springframework/boot/autoconfigure/webservices/**"); - patterns.add("org/springframework/boot/autoconfigure/jackson/**"); - - patterns.add("com/fasterxml/jackson/**"); - } - - protected void addApiDoc(Set patterns){ - patterns.add("springfox/documentation/**"); - patterns.add("io/swagger/**"); - patterns.add("org/springdoc/**"); - } - - protected void addDbDriver(Set patterns){ - // mysql - patterns.add("com/mysql/**"); - // oracle - patterns.add("oracle/jdbc/**"); - // sqlserver - patterns.add("com/microsoft/jdbc/sqlserver/**"); - // DB2 - patterns.add("com/ibm/db2/jdbc/**"); - // DB2/AS400 - patterns.add("com/ibm/as400/**"); - // Informix - patterns.add("com/informix/jdbc/**"); - // Hypersonic - patterns.add("org/hsql/**"); - // MS SQL - patterns.add("com/microsoft/jdbc/**"); - // Postgres - patterns.add("org/postgresql/**"); - // Sybase - patterns.add("com/sybase/jdbc2/**"); - // Weblogic - patterns.add("weblogic/jdbc/**"); - // h2 - patterns.add("jdbc/h2/**"); - } - - private void addIdea(Set includeResourcePatterns) { - // idea debug agent - includeResourcePatterns.add("com/intellij/rt/debugger/agent/**"); - } - - /** - * 获取基本的 MainResourcePatternDefiner - * @param pluginInteractive PluginInteractive - * @return BasicMainResourcePatternDefiner - */ - private BasicMainResourcePatternDefiner getPatternDefiner(PluginInteractive pluginInteractive){ - final MainApplicationContext mainApplicationContext = pluginInteractive.getMainApplicationContext(); - BasicMainResourcePatternDefiner definer = SpringBeanCustomUtils.getExistBean( - mainApplicationContext, BasicMainResourcePatternDefiner.class); - if(definer == null){ - return new BasicMainResourcePatternDefiner(mainPackage); - } else { - return definer; - } - } - } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java index 42a8557..b99e55e 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java @@ -16,6 +16,7 @@ package com.gitee.starblues.integration; +import com.gitee.starblues.common.Constants; import com.gitee.starblues.integration.decrypt.DecryptConfiguration; import com.gitee.starblues.utils.Assert; @@ -83,7 +84,7 @@ public abstract class DefaultIntegrationConfiguration implements IntegrationConf @Override public String version() { - return "0.0.0"; + return Constants.ALLOW_VERSION; } @Override 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 cd7944e..79f43b5 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 @@ -18,15 +18,19 @@ 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.MainResourceMatcher; import com.gitee.starblues.core.descriptor.decrypt.DefaultPluginDescriptorDecrypt; import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.core.launcher.plugin.BasicMainResourcePatternDefiner; +import com.gitee.starblues.core.launcher.plugin.DefaultMainResourcePatternDefiner; import com.gitee.starblues.integration.operator.DefaultPluginOperator; import com.gitee.starblues.integration.operator.PluginOperator; import com.gitee.starblues.integration.operator.PluginOperatorWrapper; import com.gitee.starblues.integration.user.DefaultPluginUser; import com.gitee.starblues.integration.user.PluginUser; import com.gitee.starblues.spring.extract.ExtractFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.*; import org.springframework.context.annotation.Bean; import org.springframework.context.support.GenericApplicationContext; @@ -34,7 +38,7 @@ import org.springframework.context.support.GenericApplicationContext; /** * 系统Bean配置 * @author starBlues - * @version 3.0.1 + * @version 3.0.3 */ public class ExtendPointConfiguration { @@ -78,9 +82,11 @@ public class ExtendPointConfiguration { } @Bean - @ConditionalOnMissingBean - public BasicMainResourcePatternDefiner mainResourcePatternDefiner(){ - return new BasicMainResourcePatternDefiner(configuration.mainPackage()); + public MainResourceMatcher mainResourceMatcher(){ + return new CacheMainResourceMatcher(new DefaultMainResourcePatternDefiner( + configuration.mainPackage(), + applicationContext + )); } @Bean 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 24b2df3..d985065 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 @@ -33,12 +33,13 @@ public interface MainApplicationContext extends ApplicationContext { Map> getConfigurableEnvironment(); /** - * If Resolve the specified main dependency against the beans defined in this factory. + * 从主程序获取依赖 * - * @param packageName 当前依赖包名称 + * @param requestingBeanName 依赖Bean名称 + * @param dependencyType 依赖类型 * @return boolean */ - boolean isResolveDependency(String packageName); + Object resolveDependency(String requestingBeanName, Class dependencyType); /** * 是否为web环境 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 27e5f25..30d9f41 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 @@ -17,6 +17,7 @@ package com.gitee.starblues.spring; import com.gitee.starblues.integration.IntegrationConfiguration; +import com.gitee.starblues.utils.ObjectUtils; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.support.GenericApplicationContext; @@ -80,8 +81,15 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme } @Override - public boolean isResolveDependency(String packageName) { - return packageName.startsWith(configuration.mainPackage()); + public Object resolveDependency(String requestingBeanName, Class dependencyType) { + if(!ObjectUtils.isEmpty(requestingBeanName) && applicationContext.containsBean(requestingBeanName)){ + return applicationContext.getBean(requestingBeanName); + } + try { + return applicationContext.getBean(dependencyType); + } catch (Exception e){ + return null; + } } @Override diff --git a/update.md b/update.md index 06ba901..daa8885 100644 --- a/update.md +++ b/update.md @@ -1,12 +1,15 @@ -1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 +1. 【新增[#I58CDB]([#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB))】 插件可触发`WebServerInitializedEvent`类型的事件 -2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) -3. 【支持】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) -4. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -5. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -6. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 +2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) +3. 【新增】插件新增`@AutowiredType`注解, 可指定依赖注入类型 +4. 【新增】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) +5. 【优化】优化静态资源文件加载问题 +6. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` +7. 【优化】优化从主程序依赖加载`Class`资源模块 +8. 【修复】`enablePluginIdRestPathPrefix`不生效问题 +9. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` +10. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 -7. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 +11. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 -8. 【优化】优化静态资源文件加载问题 -9. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` \ No newline at end of file +12. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 -- Gitee From 92c0f949bc5601a64e91e4f279e07dd9b53f0c63 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 29 May 2022 12:23:07 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/update.md b/update.md index daa8885..534b664 100644 --- a/update.md +++ b/update.md @@ -1,15 +1,13 @@ -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. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -9. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -10. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 -插件`Controller`使用`Aop`后, 获取不到参数 -11. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 -主程序打包参数`libDir`不生效问题 -12. 【修复】修复主程序配置`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. 【优化】优化静态资源文件加载问题 +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`导致出现版本校验失败的问题 -- Gitee From 0392a362923ac8c557e1fc32233401d2bf9efe51 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Tue, 31 May 2022 21:35:20 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=3Doptimize=20env=E3=80=81fix=20Autowired?= =?UTF-8?q?Type=20sort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EmptyMainApplicationContext.java | 8 ++ .../bootstrap/PluginContextHolder.java | 122 ++++++++++++++++++ .../bootstrap/PluginListableBeanFactory.java | 3 +- .../bootstrap/PluginSpringApplication.java | 1 + .../PluginWebApplicationContext.java | 12 +- .../bootstrap/annotation/AutowiredType.java | 17 +-- .../processor/DefaultProcessorContext.java | 6 +- .../processor/FrameDefineBeanProcessor.java | 13 -- .../bootstrap/processor/ProcessorContext.java | 1 + .../gitee/starblues/utils/MapValueGetter.java | 55 +++----- .../starblues/utils/ObjectValueUtils.java | 90 +++++++++++++ .../starblues/core/PluginLauncherManager.java | 3 +- .../MainResourcePatternDefiner.java | 2 - .../spring/MainApplicationContext.java | 10 ++ .../spring/MainApplicationContextProxy.java | 15 ++- .../environment/EmptyEnvironmentProvider.java | 22 ++-- .../environment/EnvironmentProvider.java | 22 +++- .../MainSpringBootEnvironmentProvider.java | 108 ++++++++++++++++ .../environment/MapEnvironmentProvider.java | 98 ++++++++------ 19 files changed, 470 insertions(+), 138 deletions(-) create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginContextHolder.java create mode 100644 spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectValueUtils.java rename spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/EmptyMainEnvironmentProvider.java => spring-brick/src/main/java/com/gitee/starblues/spring/environment/EmptyEnvironmentProvider.java (75%) rename spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/MainEnvironmentProvider.java => spring-brick/src/main/java/com/gitee/starblues/spring/environment/EnvironmentProvider.java (80%) create mode 100644 spring-brick/src/main/java/com/gitee/starblues/spring/environment/MainSpringBootEnvironmentProvider.java rename spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java => spring-brick/src/main/java/com/gitee/starblues/spring/environment/MapEnvironmentProvider.java (36%) 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 34c6c9c..7608046 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 0000000..7a50bab --- /dev/null +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginContextHolder.java @@ -0,0 +1,122 @@ +/** + * 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; +import lombok.Getter; + +/** + * 提供插件上下文的工具类 + * + * @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(); + } + + /** + * 获取插件的 classloader + * @return ClassLoader + */ + public static ClassLoader getPluginClassLoader() { + check(); + return pluginClassLoader; + } + + /** + * 获取插件信息 + * @return InsidePluginDescriptor + */ + public static InsidePluginDescriptor getPluginDescriptor() { + check(); + return pluginDescriptor; + } + + /** + * 获取主程序针对本框架的配置内容 + * @return IntegrationConfiguration + */ + public static IntegrationConfiguration getConfiguration() { + check(); + return configuration; + } + + /** + * 判断主程序是否为web环境 + * @return Boolean + */ + public static Boolean getMainIsWebEnv() { + check(); + return mainIsWebEnv; + } + + /** + * 获取主程序的 SpringBeanFactory . 通过它可获取主程序中的Bean + * @return SpringBeanFactory + */ + public static SpringBeanFactory getMainSpringBeanFactory() { + check(); + return mainSpringBeanFactory; + } + + 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 3aef325..f79657d 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 @@ -127,7 +127,7 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { if(autowiredType != null){ return autowiredType.value(); } else { - return AutowiredType.Type.PLUGIN_MAIN; + return AutowiredType.Type.PLUGIN; } } @@ -268,7 +268,6 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Override public Stream orderedStream() { if(isDisabled(descriptor)){ - // TODO 随意排序 return getStreamOfMain().sorted(); } else { return pluginObjectProvider.orderedStream(); 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 abdb79f..d923a1b 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 64bb67f..9539cb3 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/annotation/AutowiredType.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/annotation/AutowiredType.java index af34b00..dd55404 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 @@ -21,25 +21,26 @@ public @interface AutowiredType { Type value() default Type.PLUGIN_MAIN; 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 d9d85e0..d0801cc 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 56fcb6a..ddbb7b8 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 db4c125..42cec5b 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-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java index 191198e..813844c 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 0000000..9f34725 --- /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/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java index de3cd39..d9b9b90 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 @@ -60,8 +60,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(); 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 5759573..1a56fe3 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/spring/MainApplicationContext.java b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java index d985065..b143ef5 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 30d9f41..ea3bde4 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-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 8180226..69ca692 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 ea68a16..a4e1fac 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 0000000..84106b3 --- /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 f71a363..6a25cb1 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); + } } -- Gitee From fc2b75d3e46f35ace855e6567a758b23f6b40b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E4=BC=9F=E5=8D=8E?= Date: Fri, 3 Jun 2022 00:09:33 +0800 Subject: [PATCH 06/11] =?UTF-8?q?1.=20=E4=BF=AE=E5=A4=8DSwaggerListener?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E6=B3=A8=E5=86=8C=E9=97=AE=E9=A2=98=202.=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0Swagger=E5=88=86=E7=BB=84=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91(=E4=B8=BB=E7=A8=8B=E5=BA=8F=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E6=97=B6=E8=B7=AF=E5=BE=84=E6=9C=80=E5=A5=BD=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E5=88=B0controller=E5=B1=82=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E9=81=8D=E5=8E=86=E5=88=B0=E6=8F=92=E4=BB=B6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultPluginListenerFactory.java | 4 +- .../integration/listener/SwaggerListener.java | 140 +++++++++++++++++- 2 files changed, 136 insertions(+), 8 deletions(-) diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java index 070659a..bb9c695 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java @@ -35,7 +35,9 @@ public class DefaultPluginListenerFactory implements PluginListenerFactory{ public DefaultPluginListenerFactory(ApplicationContext applicationContext){ listeners = new ArrayList<>(); - addPluginListener(new SwaggerListener(applicationContext)); + + // bug 存在二次创建SwaggerListener对象 + //addPluginListener(new SwaggerListener(applicationContext)); addExtendPluginListener(applicationContext); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java index a8b4009..c2f9cae 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java @@ -17,43 +17,112 @@ package com.gitee.starblues.integration.listener; import com.gitee.starblues.core.PluginInfo; +import com.gitee.starblues.core.descriptor.PluginDescriptor; +import com.gitee.starblues.loader.utils.ObjectUtils; import com.gitee.starblues.utils.SpringBeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; +import org.springframework.plugin.core.PluginRegistry; +import org.springframework.plugin.core.PluginRegistrySupport; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.DocumentationPlugin; +import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + /** * Swagger 监听事件 * @author starBlues * @version 3.0.0 */ public class SwaggerListener implements PluginListener{ - private final Logger log = LoggerFactory.getLogger(this.getClass()); private final ApplicationContext mainApplicationContext; + private static List parameterList = new ArrayList<>(); + + /** + * 设置全局头部/参数 + * ParameterBuilder tokenPar = new ParameterBuilder(); + * tokenPar.name("参数名称").description("参数描述").modelRef(new ModelRef("参数数据类型")).parameterType("header或者query等").required(false); + * Parameter param = tokenPar.build(); + * @param parameters + */ + public static void setParameters(List parameters){ + parameterList = parameters; + } + public SwaggerListener(ApplicationContext mainApplicationContext) { this.mainApplicationContext = mainApplicationContext; } @Override public void startSuccess(PluginInfo pluginInfo) { - if(pluginInfo.isFollowSystem()){ - return; + Docket docket = this.createDocket(pluginInfo); + String groupName = docket.getGroupName(); + PluginRegistry pluginRegistry = this.getPluginRegistry(); + List plugins = pluginRegistry.getPlugins(); + List newPlugins = new ArrayList(); + for(DocumentationPlugin plugin : plugins){ + if(plugin.getGroupName().equals(groupName)){ + continue; + } + newPlugins.add(plugin); + } + newPlugins.add(docket); + try { + Field field = PluginRegistrySupport.class.getDeclaredField("plugins"); + field.setAccessible(true); + field.set(pluginRegistry, newPlugins); + // 如果第一次启动且为跟随系统启动的插件,减少刷新 + if(!pluginInfo.isFollowSystem() || pluginInfo.getStopTime() != null){ + this.refresh(); + } + log.debug("插件[{}]注册到swagger成功",pluginInfo.getPluginId()); + } catch (NoSuchFieldException | IllegalAccessException e) { + log.error("插件[{}]注册到swagger失败,错误为:{}", pluginInfo.getPluginId(),e.getMessage()); } - refresh(); } @Override public void stopSuccess(PluginInfo pluginInfo) { - refresh(); + String groupName = getGroupName(pluginInfo); + + PluginRegistry pluginRegistry = this.getPluginRegistry(); + List plugins = pluginRegistry.getPlugins(); + List newPlugins = new ArrayList(); + for(DocumentationPlugin plugin : plugins){ + if(groupName.equalsIgnoreCase(plugin.getGroupName())){ + continue; + } + newPlugins.add(plugin); + } + try{ + Field field = PluginRegistrySupport.class.getDeclaredField("plugins"); + field.setAccessible(true); + field.set(pluginRegistry, newPlugins); + + this.refresh(); + log.debug("插件[{}]从swagger移除成功",pluginInfo.getPluginId()); + } + catch (NoSuchFieldException | IllegalAccessException e) { + log.error("插件[{}]从swagger移除失败,错误为:{}", pluginInfo.getPluginId(),e.getMessage()); + } } void refresh(){ try { - DocumentationPluginsBootstrapper documentationPluginsBootstrapper = SpringBeanUtils.getExistBean(mainApplicationContext, - DocumentationPluginsBootstrapper.class); + DocumentationPluginsBootstrapper documentationPluginsBootstrapper = this.getDocumentationPluginsBootstrapper(); if(documentationPluginsBootstrapper != null){ documentationPluginsBootstrapper.stop(); documentationPluginsBootstrapper.start(); @@ -66,4 +135,61 @@ public class SwaggerListener implements PluginListener{ } } + /** + * 获取文档Bootstrapper + * @return + */ + private DocumentationPluginsBootstrapper getDocumentationPluginsBootstrapper(){ + DocumentationPluginsBootstrapper documentationPluginsBootstrapper = SpringBeanUtils.getExistBean(mainApplicationContext,DocumentationPluginsBootstrapper.class); + return documentationPluginsBootstrapper; + } + + /** + * 获取文档PluginRegistry + * @return + */ + private PluginRegistry getPluginRegistry(){ + PluginRegistry pluginRegistry = SpringBeanUtils.getExistBean(mainApplicationContext,"documentationPluginRegistry"); + return pluginRegistry; + } + /** + * 创建swagger分组对象 + * @param pluginInfo + * @return + */ + private Docket createDocket(PluginInfo pluginInfo) { + PluginDescriptor pluginDescriptor = pluginInfo.getPluginDescriptor(); + String description = pluginInfo.getPluginDescriptor().getDescription(); + if (ObjectUtils.isEmpty(description)) { + description = pluginDescriptor.getPluginId(); + } + + String provider = pluginDescriptor.getProvider(); + String pluginBootstrapClass = pluginDescriptor.getPluginBootstrapClass(); + String pluginClass = pluginBootstrapClass.substring(0,pluginBootstrapClass.lastIndexOf(".")); + Contact contact = new Contact(provider, "", ""); + ApiInfo apiInfo = (new ApiInfoBuilder()).title(getGroupName(pluginInfo)).description(description).contact(contact).version(pluginDescriptor.getPluginVersion()).build(); + Docket docket = (new Docket(DocumentationType.SWAGGER_2)) + .apiInfo(apiInfo).select() + .apis(RequestHandlerSelectors.basePackage(pluginClass)) + .paths(PathSelectors.any()).build() + .groupName(getGroupName(pluginInfo)); + if(parameterList != null && !parameterList.isEmpty()){ + return docket.globalOperationParameters(parameterList); + } + return docket; + } + + /** + * 获取组名称 + * @param pluginInfo + * @return + */ + private String getGroupName(PluginInfo pluginInfo){ + String description = pluginInfo.getPluginDescriptor().getDescription(); + if (ObjectUtils.isEmpty(description)) { + description = pluginInfo.getPluginId(); + } + return description +"@" +pluginInfo.getPluginId(); + } } -- Gitee From 158295f78d099217635ba44f78b8e5061b297326 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 5 Jun 2022 12:38:57 +0800 Subject: [PATCH 07/11] update to 3.0.3 --- .../bootstrap/AutowiredTypeDefinerConfig.java | 58 +++++ .../bootstrap/AutowiredTypeResolver.java | 73 +++++++ .../ConfigureMainPluginEnvironment.java | 1 + .../bootstrap/PluginListableBeanFactory.java | 198 ++++++++++-------- .../bootstrap/SpringPluginBootstrap.java | 14 +- .../bootstrap/annotation/AutowiredType.java | 6 +- .../web/PluginControllerProcessor.java | 93 +++----- .../realize/AutowiredTypeDefiner.java | 95 +++++++++ .../realize/PluginCloseListener.java | 1 + .../bootstrap/realize/StopValidator.java | 32 ++- .../com/gitee/starblues/utils/UrlUtils.java | 48 ++++- .../starblues/core/PluginLauncherManager.java | 8 +- .../classloader/CacheMainResourceMatcher.java | 3 + .../DefaultMainResourceMatcher.java | 26 +-- .../web/PluginStaticResourceResolver.java | 6 +- update.md | 31 +-- 16 files changed, 489 insertions(+), 204 deletions(-) create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeDefinerConfig.java create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/AutowiredTypeResolver.java create mode 100644 spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/AutowiredTypeDefiner.java 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 0000000..2481c0b --- /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 0000000..cdbf345 --- /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 c2e0080..912f254 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/PluginListableBeanFactory.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginListableBeanFactory.java index f79657d..f3920cc 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; - } + 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,113 +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)){ - 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/SpringPluginBootstrap.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/SpringPluginBootstrap.java index b54de8b..14d882a 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 dd55404..1d9d583 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,12 +18,12 @@ public @interface AutowiredType { * 插件Bean注入类型 * @return Type */ - Type value() default Type.PLUGIN_MAIN; + Type value() default Type.PLUGIN; - enum Type{ + enum Type{ /** - * Bean 注入类型: 仅插件 (默认) + * Bean 注入类型: 仅插件(默认) */ PLUGIN, 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 a23b314..3840ab5 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 0000000..a81d519 --- /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 dfdfd66..7942eae 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 be1d74d..54e58a0 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/UrlUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/UrlUtils.java index 90b80db..e4c7bdd 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 d9b9b90..a7b4f05 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{ @@ -123,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 ff90653..84c2a4f 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 8c82daa..1dc02c3 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/spring/web/PluginStaticResourceResolver.java b/spring-brick/src/main/java/com/gitee/starblues/spring/web/PluginStaticResourceResolver.java index 4e6c89a..3a2d192 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 534b664..dcbabbc 100644 --- a/update.md +++ b/update.md @@ -1,13 +1,18 @@ -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. 【优化】优化静态资源文件加载问题 +6. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` +7. 【优化】优化从主程序依赖加载`Class`资源模块 +8. 【优化】优化插件中注入异常提示 +9. 【优化】优化`Swagger`相关功能 +10. 【修复】`enablePluginIdRestPathPrefix`不生效问题 +11. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` +12. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 +13. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 +14. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 +15. 【修复】修复`StopValidator`禁止插件停止时, 插件状态变为`STOPPED_FAILURE`问题 + + +- 注意: 本次升级后, 从主程序注入的`Bean`, 需设置注入类型, 详见文档: [插件中注入主程序Bean说明](https://www.yuque.com/starblues/spring-brick-3.0.0/vot8gg) \ No newline at end of file -- Gitee From 7e9727ec76343c60477c25e466d7baf6c9177233 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 5 Jun 2022 12:41:51 +0800 Subject: [PATCH 08/11] update update.md --- update.md | 1 + 1 file changed, 1 insertion(+) diff --git a/update.md b/update.md index dcbabbc..e1791a5 100644 --- a/update.md +++ b/update.md @@ -13,6 +13,7 @@ 13. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 14. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 15. 【修复】修复`StopValidator`禁止插件停止时, 插件状态变为`STOPPED_FAILURE`问题 +16. 【修复】解决`jdk17`反射问题, 导致无法注册插件`Controller`问题 - 注意: 本次升级后, 从主程序注入的`Bean`, 需设置注入类型, 详见文档: [插件中注入主程序Bean说明](https://www.yuque.com/starblues/spring-brick-3.0.0/vot8gg) \ No newline at end of file -- Gitee From 0ebe657553232e1f4801a4206a8336e36fecc2e2 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 5 Jun 2022 13:05:46 +0800 Subject: [PATCH 09/11] update 3.0.3 --- .../bootstrap/PluginContextHolder.java | 41 +++++++++---------- .../integration/user/DefaultPluginUser.java | 4 +- .../starblues/spring/SpringBeanFactory.java | 2 + update.md | 25 +++++------ 4 files changed, 38 insertions(+), 34 deletions(-) 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 index 7a50bab..253c894 100644 --- 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 @@ -21,7 +21,6 @@ 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; -import lombok.Getter; /** * 提供插件上下文的工具类 @@ -69,48 +68,48 @@ public abstract class PluginContextHolder { } /** - * 获取插件的 classloader - * @return ClassLoader + * 获取主程序针对本框架的配置内容 + * @return IntegrationConfiguration */ - public static ClassLoader getPluginClassLoader() { + public static IntegrationConfiguration getConfiguration() { check(); - return pluginClassLoader; + return configuration; } /** - * 获取插件信息 - * @return InsidePluginDescriptor + * 获取主程序的 SpringBeanFactory . 通过它可获取主程序中的Bean + * @return SpringBeanFactory */ - public static InsidePluginDescriptor getPluginDescriptor() { + public static SpringBeanFactory getMainSpringBeanFactory() { check(); - return pluginDescriptor; + return mainSpringBeanFactory; } /** - * 获取主程序针对本框架的配置内容 - * @return IntegrationConfiguration + * 判断主程序是否为web环境 + * @return Boolean */ - public static IntegrationConfiguration getConfiguration() { + public static Boolean getMainIsWebEnv() { check(); - return configuration; + return mainIsWebEnv; } /** - * 判断主程序是否为web环境 - * @return Boolean + * 获取插件的 classloader + * @return ClassLoader */ - public static Boolean getMainIsWebEnv() { + public static ClassLoader getPluginClassLoader() { check(); - return mainIsWebEnv; + return pluginClassLoader; } /** - * 获取主程序的 SpringBeanFactory . 通过它可获取主程序中的Bean - * @return SpringBeanFactory + * 获取插件信息 + * @return InsidePluginDescriptor */ - public static SpringBeanFactory getMainSpringBeanFactory() { + public static InsidePluginDescriptor getPluginDescriptor() { check(); - return mainSpringBeanFactory; + return pluginDescriptor; } private static void check(){ 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 d63c705..a4a1389 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/SpringBeanFactory.java b/spring-brick/src/main/java/com/gitee/starblues/spring/SpringBeanFactory.java index 8830eed..545728f 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/update.md b/update.md index e1791a5..6bbe377 100644 --- a/update.md +++ b/update.md @@ -2,18 +2,19 @@ 2. 【新增】插件`dev`模式打包, 新增`localJars`配置(配置本地`jar`依赖文件) 3. 【新增】插件新增`@AutowiredType`注解, 可指定依赖注入类型 4. 【新增】支持插件`Controller`可不配置地址前缀(配置后会影响插件拦截器和静态资源访问) -5. 【优化】优化静态资源文件加载问题 -6. 【优化】优化插件在某些版本的`idea`中缺失`debug`包, 导致无法`debug` -7. 【优化】优化从主程序依赖加载`Class`资源模块 -8. 【优化】优化插件中注入异常提示 -9. 【优化】优化`Swagger`相关功能 -10. 【修复】`enablePluginIdRestPathPrefix`不生效问题 -11. 【修复】插件无法注入`ObjectProvider`、`ObjectFactory`类型为主程序的`Bean` -12. 【修复[#I58CDB](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58CDB)】 插件`Controller`使用`Aop`后, 获取不到参数 -13. 【修复[#I58GCI](https://gitee.com/starblues/springboot-plugin-framework-parent/issues/I58GCI)】 主程序打包参数`libDir`不生效问题 -14. 【修复】修复主程序配置`version`, 插件未配置`requires`导致出现版本校验失败的问题 -15. 【修复】修复`StopValidator`禁止插件停止时, 插件状态变为`STOPPED_FAILURE`问题 -16. 【修复】解决`jdk17`反射问题, 导致无法注册插件`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 -- Gitee From b4ebdc825f7ef9888b8eeb75670105807a9b451c Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 5 Jun 2022 13:30:14 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Eswagger=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E5=99=A8=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultPluginListenerFactory.java | 6 +- .../integration/listener/SwaggerListener.java | 87 +++++++++++-------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java index bb9c695..bce94ea 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/DefaultPluginListenerFactory.java @@ -27,7 +27,8 @@ import java.util.List; /** * 默认的插件工厂 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public class DefaultPluginListenerFactory implements PluginListenerFactory{ @@ -35,9 +36,6 @@ public class DefaultPluginListenerFactory implements PluginListenerFactory{ public DefaultPluginListenerFactory(ApplicationContext applicationContext){ listeners = new ArrayList<>(); - - // bug 存在二次创建SwaggerListener对象 - //addPluginListener(new SwaggerListener(applicationContext)); addExtendPluginListener(applicationContext); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java index c2f9cae..a75d6fb 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/listener/SwaggerListener.java @@ -19,6 +19,7 @@ package com.gitee.starblues.integration.listener; import com.gitee.starblues.core.PluginInfo; import com.gitee.starblues.core.descriptor.PluginDescriptor; import com.gitee.starblues.loader.utils.ObjectUtils; +import com.gitee.starblues.utils.MsgUtils; import com.gitee.starblues.utils.SpringBeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,9 +44,11 @@ import java.util.List; /** * Swagger 监听事件 * @author starBlues - * @version 3.0.0 + * @since 3.0.0 + * @version 3.0.3 */ public class SwaggerListener implements PluginListener{ + private final Logger log = LoggerFactory.getLogger(this.getClass()); private final ApplicationContext mainApplicationContext; @@ -54,9 +57,13 @@ public class SwaggerListener implements PluginListener{ /** * 设置全局头部/参数 * ParameterBuilder tokenPar = new ParameterBuilder(); - * tokenPar.name("参数名称").description("参数描述").modelRef(new ModelRef("参数数据类型")).parameterType("header或者query等").required(false); + * tokenPar.name("参数名称") + * .description("参数描述") + * .modelRef(new ModelRef("参数数据类型")) + * .parameterType("header或者query等") + * .required(false); * Parameter param = tokenPar.build(); - * @param parameters + * @param parameters parameters */ public static void setParameters(List parameters){ parameterList = parameters; @@ -68,11 +75,12 @@ public class SwaggerListener implements PluginListener{ @Override public void startSuccess(PluginInfo pluginInfo) { - Docket docket = this.createDocket(pluginInfo); + PluginDescriptor descriptor = pluginInfo.getPluginDescriptor(); + Docket docket = this.createDocket(descriptor); String groupName = docket.getGroupName(); PluginRegistry pluginRegistry = this.getPluginRegistry(); List plugins = pluginRegistry.getPlugins(); - List newPlugins = new ArrayList(); + List newPlugins = new ArrayList<>(); for(DocumentationPlugin plugin : plugins){ if(plugin.getGroupName().equals(groupName)){ continue; @@ -88,19 +96,20 @@ public class SwaggerListener implements PluginListener{ if(!pluginInfo.isFollowSystem() || pluginInfo.getStopTime() != null){ this.refresh(); } - log.debug("插件[{}]注册到swagger成功",pluginInfo.getPluginId()); + log.debug("插件[{}]注册到 Swagger 成功", pluginInfo.getPluginId()); } catch (NoSuchFieldException | IllegalAccessException e) { - log.error("插件[{}]注册到swagger失败,错误为:{}", pluginInfo.getPluginId(),e.getMessage()); + log.error("插件[{}]注册到 Swagger 失败,错误为:{}", pluginInfo.getPluginId(),e.getMessage()); } } @Override public void stopSuccess(PluginInfo pluginInfo) { - String groupName = getGroupName(pluginInfo); + PluginDescriptor descriptor = pluginInfo.getPluginDescriptor(); + String groupName = getGroupName(descriptor); PluginRegistry pluginRegistry = this.getPluginRegistry(); List plugins = pluginRegistry.getPlugins(); - List newPlugins = new ArrayList(); + List newPlugins = new ArrayList<>(); for(DocumentationPlugin plugin : plugins){ if(groupName.equalsIgnoreCase(plugin.getGroupName())){ continue; @@ -113,10 +122,10 @@ public class SwaggerListener implements PluginListener{ field.set(pluginRegistry, newPlugins); this.refresh(); - log.debug("插件[{}]从swagger移除成功",pluginInfo.getPluginId()); + log.debug("插件[{}]从 Swagger 移除成功", MsgUtils.getPluginUnique(descriptor)); } catch (NoSuchFieldException | IllegalAccessException e) { - log.error("插件[{}]从swagger移除失败,错误为:{}", pluginInfo.getPluginId(),e.getMessage()); + log.error("插件[{}]从 Swagger 移除失败,错误为:{}", MsgUtils.getPluginUnique(descriptor), e.getMessage()); } } @@ -131,49 +140,55 @@ public class SwaggerListener implements PluginListener{ } } catch (Exception e){ // ignore - log.warn("refresh swagger failure"); + log.warn("refresh swagger failure. {}", e.getMessage()); } } /** - * 获取文档Bootstrapper - * @return + * 获取文档 Bootstrapper + * @return DocumentationPluginsBootstrapper */ private DocumentationPluginsBootstrapper getDocumentationPluginsBootstrapper(){ - DocumentationPluginsBootstrapper documentationPluginsBootstrapper = SpringBeanUtils.getExistBean(mainApplicationContext,DocumentationPluginsBootstrapper.class); - return documentationPluginsBootstrapper; + return SpringBeanUtils.getExistBean(mainApplicationContext, DocumentationPluginsBootstrapper.class); } /** * 获取文档PluginRegistry - * @return + * @return PluginRegistry */ private PluginRegistry getPluginRegistry(){ - PluginRegistry pluginRegistry = SpringBeanUtils.getExistBean(mainApplicationContext,"documentationPluginRegistry"); - return pluginRegistry; + return SpringBeanUtils.getExistBean(mainApplicationContext,"documentationPluginRegistry"); } + /** * 创建swagger分组对象 - * @param pluginInfo - * @return + * + * @param descriptor 插件信息 + * @return Docket */ - private Docket createDocket(PluginInfo pluginInfo) { - PluginDescriptor pluginDescriptor = pluginInfo.getPluginDescriptor(); - String description = pluginInfo.getPluginDescriptor().getDescription(); + private Docket createDocket(PluginDescriptor descriptor) { + String description = descriptor.getDescription(); if (ObjectUtils.isEmpty(description)) { - description = pluginDescriptor.getPluginId(); + description = descriptor.getPluginId(); } - String provider = pluginDescriptor.getProvider(); - String pluginBootstrapClass = pluginDescriptor.getPluginBootstrapClass(); - String pluginClass = pluginBootstrapClass.substring(0,pluginBootstrapClass.lastIndexOf(".")); + String provider = descriptor.getProvider(); + String pluginBootstrapClass = descriptor.getPluginBootstrapClass(); + String pluginClass = pluginBootstrapClass.substring(0, pluginBootstrapClass.lastIndexOf(".")); Contact contact = new Contact(provider, "", ""); - ApiInfo apiInfo = (new ApiInfoBuilder()).title(getGroupName(pluginInfo)).description(description).contact(contact).version(pluginDescriptor.getPluginVersion()).build(); + ApiInfo apiInfo = new ApiInfoBuilder() + .title(getGroupName(descriptor)) + .description(description) + .contact(contact) + .version(descriptor.getPluginVersion()) + .build(); + Docket docket = (new Docket(DocumentationType.SWAGGER_2)) .apiInfo(apiInfo).select() .apis(RequestHandlerSelectors.basePackage(pluginClass)) .paths(PathSelectors.any()).build() - .groupName(getGroupName(pluginInfo)); + .groupName(getGroupName(descriptor)); + if(parameterList != null && !parameterList.isEmpty()){ return docket.globalOperationParameters(parameterList); } @@ -182,14 +197,10 @@ public class SwaggerListener implements PluginListener{ /** * 获取组名称 - * @param pluginInfo - * @return + * @param descriptor 插件信息 + * @return 分组信息 */ - private String getGroupName(PluginInfo pluginInfo){ - String description = pluginInfo.getPluginDescriptor().getDescription(); - if (ObjectUtils.isEmpty(description)) { - description = pluginInfo.getPluginId(); - } - return description +"@" +pluginInfo.getPluginId(); + private String getGroupName(PluginDescriptor descriptor){ + return descriptor.getPluginId() +"@" + descriptor.getPluginVersion(); } } -- Gitee From 0238cb23d91e07e0c5a568cb3d64e5ac3584f5b5 Mon Sep 17 00:00:00 2001 From: StarBlues Date: Mon, 6 Jun 2022 21:05:20 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=3DObjectProvider=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootstrap/PluginListableBeanFactory.java | 143 ++++++++++++------ .../spring/MainApplicationContextProxy.java | 3 - 2 files changed, 97 insertions(+), 49 deletions(-) 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 f3920cc..76e8f7f 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,14 +18,10 @@ 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; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; import com.gitee.starblues.utils.ReflectionUtils; -import lombok.AllArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -35,7 +31,6 @@ 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.*; @@ -68,6 +63,14 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { AutowiredType.Type autowiredType = getAutowiredType(descriptor); + Class dependencyType = descriptor.getDependencyType(); + if (dependencyType == ObjectFactory.class || dependencyType == ObjectProvider.class) { + Object dependencyObj = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + typeConverter); + ObjectProvider provider = (ObjectProvider) dependencyObj; + return new PluginObjectProviderWrapper(provider, requestingBeanName, descriptor, autowiredType); + } + if(autowiredType == AutowiredType.Type.MAIN){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); if(dependencyObj != null){ @@ -78,14 +81,8 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ try { - Object dependencyObj = super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, + return super.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); - - if(dependencyObj instanceof ObjectProvider){ - ObjectProvider provider = (ObjectProvider) dependencyObj; - return new PluginObjectProviderWrapper(provider, requestingBeanName, descriptor, autowiredType); - } - return dependencyObj; } catch (BeansException e){ if(e instanceof NoSuchBeanDefinitionException){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); @@ -154,7 +151,6 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { } - @AllArgsConstructor private class PluginObjectProviderWrapper implements ObjectProvider { private final ObjectProvider pluginObjectProvider; @@ -163,36 +159,55 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { private final DependencyDescriptor descriptor; private final AutowiredType.Type autowiredType; + private PluginObjectProviderWrapper(ObjectProvider pluginObjectProvider, + String requestingBeanName, + DependencyDescriptor descriptor, + AutowiredType.Type autowiredType) { + this.pluginObjectProvider = pluginObjectProvider; + this.requestingBeanName = requestingBeanName; + this.descriptor = new NestedDependencyDescriptor(descriptor); + this.autowiredType = autowiredType; + } + @Override public Object getObject() throws BeansException { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + if(autowiredType == AutowiredType.Type.PLUGIN) { + return pluginObjectProvider.getObject(); + } else if(autowiredType == AutowiredType.Type.MAIN){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); if(dependencyObj != null){ return dependencyObj; } - return pluginObjectProvider.getObject(); - } else { + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN) { try { return pluginObjectProvider.getObject(); - } catch (Exception e){ + } catch (Exception e) { Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); - if(dependencyObj != null){ + if (dependencyObj != null) { return dependencyObj; } throw e; } + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getObject(); } + throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType()); } @Override public Object getObject(final Object... args) throws BeansException { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + if(autowiredType == AutowiredType.Type.PLUGIN){ + return pluginObjectProvider.getObject(args); + } else if(autowiredType == AutowiredType.Type.MAIN){ Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); if(dependencyObj != null){ return dependencyObj; } - return pluginObjectProvider.getObject(args); - } else { + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ try { return pluginObjectProvider.getObject(); } catch (Exception e){ @@ -203,25 +218,37 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { } throw e; } + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getObject(args); } + throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType()); } @Override @Nullable public Object getIfAvailable() throws BeansException { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ - Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); - if(dependencyObj != null){ - return dependencyObj; - } + if(autowiredType == AutowiredType.Type.PLUGIN){ return pluginObjectProvider.getIfAvailable(); - } else { + } else if(autowiredType == AutowiredType.Type.MAIN){ + return resolveDependencyFromMain(requestingBeanName, descriptor); + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ Object dependencyObj = pluginObjectProvider.getIfAvailable(); if(dependencyObj == null){ dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); } return dependencyObj; + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getIfAvailable(); } + return null; } @Override @@ -235,19 +262,24 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Override @Nullable public Object getIfUnique() throws BeansException { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ - Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); - if(dependencyObj != null){ - return dependencyObj; - } + if(autowiredType == AutowiredType.Type.PLUGIN){ return pluginObjectProvider.getIfUnique(); - } else { + } else if(autowiredType == AutowiredType.Type.MAIN){ + return resolveDependencyFromMain(requestingBeanName, descriptor); + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ Object dependencyObj = pluginObjectProvider.getIfUnique(); if(dependencyObj == null){ dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); } return dependencyObj; + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Object dependencyObj = resolveDependencyFromMain(requestingBeanName, descriptor); + if(dependencyObj != null){ + return dependencyObj; + } + return pluginObjectProvider.getIfUnique(); } + return null; } @Override @@ -260,38 +292,48 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { @Override public Stream stream() { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ - Set collection = getStreamOfMain(); - if(!collection.isEmpty()){ - return collection.stream(); - } + if(autowiredType == AutowiredType.Type.PLUGIN){ return pluginObjectProvider.stream(); - } else { + } else if(autowiredType == AutowiredType.Type.MAIN){ + return getStreamOfMain().stream(); + } else if (autowiredType == AutowiredType.Type.PLUGIN_MAIN){ Stream stream = pluginObjectProvider.stream(); List collect = stream.collect(Collectors.toList()); if(!collect.isEmpty()){ return collect.stream(); } return getStreamOfMain().stream(); + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Set collection = getStreamOfMain(); + if(!collection.isEmpty()){ + return collection.stream(); + } + return pluginObjectProvider.stream(); } + return Stream.empty(); } @Override public Stream orderedStream() { - if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ - Set collection = getStreamOfMain(); - if(!collection.isEmpty()){ - return collection.stream().sorted(); - } - return pluginObjectProvider.stream(); - } else { + if(autowiredType == AutowiredType.Type.PLUGIN){ + return pluginObjectProvider.orderedStream(); + } else if(autowiredType == AutowiredType.Type.MAIN){ + return getStreamOfMain().stream().sorted(); + } else if(autowiredType == AutowiredType.Type.PLUGIN_MAIN){ Stream stream = pluginObjectProvider.stream(); List collect = stream.collect(Collectors.toList()); if(!collect.isEmpty()){ return collect.stream(); } return getStreamOfMain().stream().sorted(); + } else if(autowiredType == AutowiredType.Type.MAIN_PLUGIN){ + Set collection = getStreamOfMain(); + if(!collection.isEmpty()){ + return collection.stream().sorted(); + } + return pluginObjectProvider.stream(); } + return Stream.empty(); } @SuppressWarnings("unchecked") @@ -302,4 +344,13 @@ public class PluginListableBeanFactory extends DefaultListableBeanFactory { } } + + private static class NestedDependencyDescriptor extends DependencyDescriptor { + + public NestedDependencyDescriptor(DependencyDescriptor original) { + super(original); + increaseNestingLevel(); + } + } + } 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 ea3bde4..4c5b61b 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 @@ -83,9 +83,6 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme @Override public Object resolveDependency(String requestingBeanName, Class dependencyType) { - if(!ObjectUtils.isEmpty(requestingBeanName) && applicationContext.containsBean(requestingBeanName)){ - return applicationContext.getBean(requestingBeanName); - } try { return applicationContext.getBean(dependencyType); } catch (Exception e){ -- Gitee