From 77ece45cf459062b4487e13c34a0f711dd896d3f Mon Sep 17 00:00:00 2001 From: beiwei30 Date: Mon, 5 Nov 2018 11:37:44 +0800 Subject: [PATCH 1/4] merge https://github.com/apache/incubator-dubbo/pull/2725 --- all/pom.xml | 10 +- dubbo-bootstrap/pom.xml | 45 ------- .../dubbo/bootstrap/DubboBootstrap.java | 111 ------------------ .../alibaba/dubbo/config/ProtocolConfig.java | 11 +- dubbo-config/dubbo-config-spring/pom.xml | 7 +- .../dubbo/config/spring/AnnotationBean.java | 23 ++-- .../dubbo/config/spring/ServiceBean.java | 30 +---- .../extension/SpringExtensionFactory.java | 21 ++++ .../config/spring/util/BeanFactoryUtils.java | 58 +++++++++ .../DubboApplicationContextInitializer.java | 39 ------ .../initializer/DubboApplicationListener.java | 49 -------- .../main/resources/META-INF/web-fragment.xml | 22 ---- ...ubboApplicationContextInitializerTest.java | 87 -------------- .../dubbo-container-spring/pom.xml | 7 +- .../container/spring/SpringContainer.java | 4 - pom.xml | 1 - 16 files changed, 99 insertions(+), 426 deletions(-) delete mode 100644 dubbo-bootstrap/pom.xml delete mode 100644 dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java delete mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializer.java delete mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListener.java delete mode 100644 dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml delete mode 100644 dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java diff --git a/all/pom.xml b/all/pom.xml index 39884493871..1de057893db 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -319,13 +319,6 @@ compile true - - com.alibaba - dubbo-bootstrap - ${project.version} - compile - true - com.alibaba hessian-lite @@ -424,7 +417,6 @@ com.alibaba:dubbo-serialization-fst com.alibaba:dubbo-serialization-kryo com.alibaba:dubbo-serialization-jdk - com.alibaba:dubbo-bootstrap @@ -588,4 +580,4 @@ - \ No newline at end of file + diff --git a/dubbo-bootstrap/pom.xml b/dubbo-bootstrap/pom.xml deleted file mode 100644 index ae6440a5bce..00000000000 --- a/dubbo-bootstrap/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - dubbo-parent - com.alibaba - 2.6.5-SNAPSHOT - - 4.0.0 - - dubbo-bootstrap - - - - - com.alibaba - dubbo-config-api - ${project.parent.version} - - - com.alibaba - dubbo-common - ${project.parent.version} - - - com.alibaba - dubbo-registry-api - ${project.parent.version} - - - \ No newline at end of file diff --git a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java deleted file mode 100644 index 37ec8a304bc..00000000000 --- a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.bootstrap; - -import com.alibaba.dubbo.config.DubboShutdownHook; -import com.alibaba.dubbo.config.ServiceConfig; - -import java.util.ArrayList; -import java.util.List; - -/** - * A bootstrap class to easily start and stop Dubbo via programmatic API. - * The bootstrap class will be responsible to cleanup the resources during stop. - */ -public class DubboBootstrap { - - /** - * The list of ServiceConfig - */ - private List serviceConfigList; - - /** - * Whether register the shutdown hook during start? - */ - private final boolean registerShutdownHookOnStart; - - /** - * The shutdown hook used when Dubbo is running under embedded environment - */ - private DubboShutdownHook shutdownHook; - - public DubboBootstrap() { - this(true, DubboShutdownHook.getDubboShutdownHook()); - } - - public DubboBootstrap(boolean registerShutdownHookOnStart) { - this(registerShutdownHookOnStart, DubboShutdownHook.getDubboShutdownHook()); - } - - public DubboBootstrap(boolean registerShutdownHookOnStart, DubboShutdownHook shutdownHook) { - this.serviceConfigList = new ArrayList(); - this.shutdownHook = shutdownHook; - this.registerShutdownHookOnStart = registerShutdownHookOnStart; - } - - /** - * Register service config to bootstrap, which will be called during {@link DubboBootstrap#stop()} - * @param serviceConfig the service - * @return the bootstrap instance - */ - public DubboBootstrap registerServiceConfig(ServiceConfig serviceConfig) { - serviceConfigList.add(serviceConfig); - return this; - } - - public void start() { - if (registerShutdownHookOnStart) { - registerShutdownHook(); - } else { - // DubboShutdown hook has been registered in AbstractConfig, - // we need to remove it explicitly - removeShutdownHook(); - } - for (ServiceConfig serviceConfig: serviceConfigList) { - serviceConfig.export(); - } - } - - public void stop() { - for (ServiceConfig serviceConfig: serviceConfigList) { - serviceConfig.unexport(); - } - shutdownHook.destroyAll(); - if (registerShutdownHookOnStart) { - removeShutdownHook(); - } - } - - /** - * Register the shutdown hook - */ - public void registerShutdownHook() { - Runtime.getRuntime().addShutdownHook(shutdownHook); - } - - /** - * Remove this shutdown hook - */ - public void removeShutdownHook() { - try { - Runtime.getRuntime().removeShutdownHook(shutdownHook); - } - catch (IllegalStateException ex) { - // ignore - VM is already shutting down - } - } -} diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java index b901beddd99..4952dfe70e2 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java @@ -459,13 +459,4 @@ public void destroy() { ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).destroy(); } } - - /** - * Just for compatibility. - * It should be deleted in the next major version, say 2.7.x. - */ - @Deprecated - public static void destroyAll() { - DubboShutdownHook.getDubboShutdownHook().destroyAll(); - } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml index 7697f6fc934..6284abcc9b4 100644 --- a/dubbo-config/dubbo-config-spring/pom.xml +++ b/dubbo-config/dubbo-config-spring/pom.xml @@ -35,11 +35,6 @@ dubbo-config-api ${project.parent.version} - - com.alibaba - dubbo-bootstrap - ${project.parent.version} - org.springframework spring-beans @@ -167,4 +162,4 @@ --> - \ No newline at end of file + diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java index 6da7ba8b901..722c6d05213 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java @@ -28,7 +28,6 @@ import com.alibaba.dubbo.config.MonitorConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.ProviderConfig; -import com.alibaba.dubbo.config.ReferenceConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.ServiceConfig; import com.alibaba.dubbo.config.annotation.Reference; @@ -112,17 +111,16 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) @Override public void destroy() { - - // This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys. - // We will guarantee dubbo related resources being released with dubbo shutdown hook. - - // for (ServiceConfig serviceConfig : serviceConfigs) { - // try { - // serviceConfig.unexport(); - // } catch (Throwable e) { - // logger.error(e.getMessage(), e); - // } - // } + // no need to destroy here + // see org.apache.dubbo.config.spring.extension.SpringExtensionFactory.ShutdownHookListener + /* + for (ServiceConfig serviceConfig : serviceConfigs) { + try { + serviceConfig.unexport(); + } catch (Throwable e) { + logger.error(e.getMessage(), e); + } + } for (ReferenceConfig referenceConfig : referenceConfigs.values()) { try { @@ -131,6 +129,7 @@ public void destroy() { logger.error(e.getMessage(), e); } } + */ } @Override diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java index 6174d1b752d..28592394149 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java @@ -38,13 +38,13 @@ import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.support.AbstractApplicationContext; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; +import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.addApplicationListener; + /** * ServiceFactoryBean * @@ -86,26 +86,7 @@ public static ApplicationContext getSpringContext() { public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; SpringExtensionFactory.addApplicationContext(applicationContext); - if (applicationContext != null) { - SPRING_CONTEXT = applicationContext; - try { - Method method = applicationContext.getClass().getMethod("addApplicationListener", new Class[]{ApplicationListener.class}); // backward compatibility to spring 2.0.1 - method.invoke(applicationContext, new Object[]{this}); - supportedApplicationListener = true; - } catch (Throwable t) { - if (applicationContext instanceof AbstractApplicationContext) { - try { - Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", new Class[]{ApplicationListener.class}); // backward compatibility to spring 2.0.1 - if (!method.isAccessible()) { - method.setAccessible(true); - } - method.invoke(applicationContext, new Object[]{this}); - supportedApplicationListener = true; - } catch (Throwable t2) { - } - } - } - } + supportedApplicationListener = addApplicationListener(applicationContext, this); } @Override @@ -303,9 +284,8 @@ private void publishExportEvent() { @Override public void destroy() throws Exception { - // This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys. - // We will guarantee dubbo related resources being released with dubbo shutdown hook. - //unexport(); + // no need to call unexport() here, see + // org.apache.dubbo.config.spring.extension.SpringExtensionFactory.ShutdownHookListener } // merged from dubbox diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java index 8673b3925fd..5735ef35d74 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java @@ -21,9 +21,14 @@ import com.alibaba.dubbo.common.logger.LoggerFactory; import com.alibaba.dubbo.common.utils.ConcurrentHashSet; +import com.alibaba.dubbo.config.DubboShutdownHook; +import com.alibaba.dubbo.config.spring.util.BeanFactoryUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; import java.util.Set; @@ -35,8 +40,11 @@ public class SpringExtensionFactory implements ExtensionFactory { private static final Set contexts = new ConcurrentHashSet(); + private static final ApplicationListener shutdownHookListener = new ShutdownHookListener(); + public static void addApplicationContext(ApplicationContext context) { contexts.add(context); + BeanFactoryUtils.addApplicationListener(context, shutdownHookListener); } public static void removeApplicationContext(ApplicationContext context) { @@ -83,4 +91,17 @@ public T getExtension(Class type, String name) { return null; } + private static class ShutdownHookListener implements ApplicationListener { + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof ContextClosedEvent) { + // we call it anyway since dubbo shutdown hook make sure its destroyAll() is re-entrant. + // pls. note we should not remove dubbo shutdown hook when spring framework is present, this is because + // its shutdown hook may not be installed. + DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook(); + shutdownHook.destroyAll(); + } + } + } + } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java new file mode 100644 index 00000000000..13a3011c0d8 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alibaba.dubbo.config.spring.util; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.support.AbstractApplicationContext; + +import java.lang.reflect.Method; + +/** + * {@link BeanFactory} Utilities class + * + * @see BeanFactory + * @see ConfigurableBeanFactory + * @see org.springframework.beans.factory.BeanFactoryUtils + */ +public class BeanFactoryUtils { + public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) { + try { + // backward compatibility to spring 2.0.1 + Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class); + method.invoke(applicationContext, listener); + return true; + } catch (Throwable t) { + if (applicationContext instanceof AbstractApplicationContext) { + try { + // backward compatibility to spring 2.0.1 + Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class); + if (!method.isAccessible()) { + method.setAccessible(true); + } + method.invoke(applicationContext, listener); + return true; + } catch (Throwable t2) { + // ignore + } + } + } + return false; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializer.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializer.java deleted file mode 100644 index 36727e669f4..00000000000 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer; - -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * Automatically register {@link DubboApplicationListener} to Spring context - * A {@link org.springframework.web.context.ContextLoaderListener} class is defined in - * src/main/resources/META-INF/web-fragment.xml - * In the web-fragment.xml, {@link DubboApplicationContextInitializer} is defined in context params. - * This file will be discovered if running under a servlet 3.0+ container. - * Even if user specifies {@link org.springframework.web.context.ContextLoaderListener} in web.xml, - * it will be merged to web.xml. - * If user specifies in web.xml, this will no take effect, - * unless user configures {@link DubboApplicationContextInitializer} explicitly in web.xml. - */ -public class DubboApplicationContextInitializer implements ApplicationContextInitializer { - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - applicationContext.addApplicationListener(new DubboApplicationListener()); - } -} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListener.java deleted file mode 100644 index 8b6409bd65f..00000000000 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListener.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer; - -import org.apache.dubbo.bootstrap.DubboBootstrap; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.ContextRefreshedEvent; - -/** - * An application listener that listens the ContextClosedEvent. - * Upon the event, this listener will do the necessary clean up to avoid memory leak. - */ -public class DubboApplicationListener implements ApplicationListener { - - private DubboBootstrap dubboBootstrap; - - public DubboApplicationListener() { - dubboBootstrap = new DubboBootstrap(false); - } - - public DubboApplicationListener(DubboBootstrap dubboBootstrap) { - this.dubboBootstrap = dubboBootstrap; - } - - @Override - public void onApplicationEvent(ApplicationEvent applicationEvent) { - if (applicationEvent instanceof ContextRefreshedEvent) { - dubboBootstrap.start(); - } else if (applicationEvent instanceof ContextClosedEvent) { - dubboBootstrap.stop(); - } - } -} diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml deleted file mode 100644 index 220874ab78c..00000000000 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - dubbo-fragment - - - - - - - - - contextInitializerClasses - org.apache.dubbo.config.spring.initializer.DubboApplicationContextInitializer - - - - org.springframework.web.context.ContextLoaderListener - - - \ No newline at end of file diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java deleted file mode 100644 index b5b8f8c9a9b..00000000000 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer; - -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.startup.ContextConfig; -import org.apache.catalina.startup.Tomcat; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.web.context.ContextLoaderListener; - - -public class DubboApplicationContextInitializerTest { - - @Test - public void testSpringContextLoaderListenerInWebXml() throws Exception { - Tomcat tomcat = new Tomcat(); - tomcat.setBaseDir("target/test-classes"); - tomcat.setPort(12345); - StandardContext context = new StandardContext(); - context.setName("test"); - context.setDocBase("test"); - context.setPath("/test"); - context.addLifecycleListener(new ContextConfig()); - tomcat.getHost().addChild(context); - tomcat.start(); - // there should be 1 application listener - Assert.assertEquals(1, context.getApplicationLifecycleListeners().length); - // the first one should be Spring's built in ContextLoaderListener. - Assert.assertTrue(context.getApplicationLifecycleListeners()[0] instanceof ContextLoaderListener); - tomcat.stop(); - tomcat.destroy(); - } - - @Test - public void testNoListenerInWebXml() throws Exception { - Tomcat tomcat = new Tomcat(); - tomcat.setBaseDir("target/test-classes"); - tomcat.setPort(12345); - StandardContext context = new StandardContext(); - context.setName("test2"); - context.setDocBase("test2"); - context.setPath("/test2"); - context.addLifecycleListener(new ContextConfig()); - tomcat.getHost().addChild(context); - tomcat.start(); - // there should be 1 application listener - Assert.assertEquals(1, context.getApplicationLifecycleListeners().length); - // the first one should be Spring's built in ContextLoaderListener. - Assert.assertTrue(context.getApplicationLifecycleListeners()[0] instanceof ContextLoaderListener); - tomcat.stop(); - tomcat.destroy(); - } - - @Test - public void testMetadataComplete() throws Exception { - Tomcat tomcat = new Tomcat(); - tomcat.setBaseDir("target/test-classes"); - tomcat.setPort(12345); - StandardContext context = new StandardContext(); - context.setName("test3"); - context.setDocBase("test3"); - context.setPath("/test3"); - context.addLifecycleListener(new ContextConfig()); - tomcat.getHost().addChild(context); - tomcat.start(); - // there should be no application listeners - Assert.assertEquals(0, context.getApplicationLifecycleListeners().length); - tomcat.stop(); - tomcat.destroy(); - } - -} diff --git a/dubbo-container/dubbo-container-spring/pom.xml b/dubbo-container/dubbo-container-spring/pom.xml index 0af93dcbf45..642ef312ffa 100644 --- a/dubbo-container/dubbo-container-spring/pom.xml +++ b/dubbo-container/dubbo-container-spring/pom.xml @@ -38,10 +38,5 @@ org.springframework spring-context - - com.alibaba - dubbo-config-spring - ${project.parent.version} - - \ No newline at end of file + diff --git a/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java b/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java index b5866f57c75..ab085ab8d41 100644 --- a/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java +++ b/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java @@ -21,7 +21,6 @@ import com.alibaba.dubbo.common.utils.ConfigUtils; import com.alibaba.dubbo.container.Container; -import org.apache.dubbo.config.spring.initializer.DubboApplicationListener; import org.springframework.context.support.ClassPathXmlApplicationContext; /** @@ -45,9 +44,6 @@ public void start() { configPath = DEFAULT_SPRING_CONFIG; } context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"), false); - context.addApplicationListener(new DubboApplicationListener()); - context.registerShutdownHook(); - context.refresh(); context.start(); } diff --git a/pom.xml b/pom.xml index f12a635924b..f5a85b118d7 100644 --- a/pom.xml +++ b/pom.xml @@ -138,7 +138,6 @@ dubbo-demo dubbo-plugin dubbo-serialization - dubbo-bootstrap dependencies-bom bom all From 6b091aae66375e1ed9a76e3259955d9436d0774d Mon Sep 17 00:00:00 2001 From: beiwei30 Date: Mon, 5 Nov 2018 11:49:14 +0800 Subject: [PATCH 2/4] fix UT failure --- .../com/alibaba/dubbo/container/spring/SpringContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java b/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java index ab085ab8d41..d21f3a5636f 100644 --- a/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java +++ b/dubbo-container/dubbo-container-spring/src/main/java/com/alibaba/dubbo/container/spring/SpringContainer.java @@ -43,7 +43,7 @@ public void start() { if (configPath == null || configPath.length() == 0) { configPath = DEFAULT_SPRING_CONFIG; } - context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"), false); + context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+")); context.start(); } From 996f9e22c7d6044bd204eab2e98762195a14de4e Mon Sep 17 00:00:00 2001 From: beiwei30 Date: Mon, 5 Nov 2018 13:49:00 +0800 Subject: [PATCH 3/4] remove useless test --- .../DubboApplicationListenerTest.java | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/initializer/DubboApplicationListenerTest.java diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/initializer/DubboApplicationListenerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/initializer/DubboApplicationListenerTest.java deleted file mode 100644 index 9220ce91768..00000000000 --- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/initializer/DubboApplicationListenerTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alibaba.dubbo.config.spring.initializer; - -import com.alibaba.dubbo.config.DubboShutdownHook; - -import org.apache.dubbo.bootstrap.DubboBootstrap; -import org.apache.dubbo.config.spring.initializer.DubboApplicationListener; -import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -public class DubboApplicationListenerTest { - - @Test - public void testTwoShutdownHook() { - DubboShutdownHook spyHook = Mockito.spy(DubboShutdownHook.getDubboShutdownHook()); - ClassPathXmlApplicationContext applicationContext = getApplicationContext(spyHook, true); - applicationContext.refresh(); - applicationContext.close(); - // shutdown hook can't be verified, because it will executed after main thread has finished. - // so we can only verify it by manually run it. - try { - spyHook.start(); - spyHook.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - Mockito.verify(spyHook, Mockito.times(2)).destroyAll(); - } - - @Test - public void testOneShutdownHook() { - DubboShutdownHook spyHook = Mockito.spy(DubboShutdownHook.getDubboShutdownHook()); - ClassPathXmlApplicationContext applicationContext = getApplicationContext(spyHook, false); - applicationContext.refresh(); - applicationContext.close(); - Mockito.verify(spyHook, Mockito.times(1)).destroyAll(); - } - - private ClassPathXmlApplicationContext getApplicationContext(DubboShutdownHook hook, boolean registerHook) { - DubboBootstrap bootstrap = new DubboBootstrap(registerHook, hook); - ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); - applicationContext.addApplicationListener(new DubboApplicationListener(bootstrap)); - return applicationContext; - } -} From 9d046ad8681cdcc1ed263ccb9f05c85f9d3808a7 Mon Sep 17 00:00:00 2001 From: beiwei30 Date: Mon, 5 Nov 2018 14:21:36 +0800 Subject: [PATCH 4/4] fix unit test failures --- .../alibaba/dubbo/config/spring/ServiceBean.java | 6 ------ .../spring/extension/SpringExtensionFactory.java | 4 ++++ .../spring/status/DataSourceStatusChecker.java | 10 ++++++++-- .../config/spring/status/SpringStatusChecker.java | 10 ++++++++-- .../spring/status/DataSourceStatusCheckerTest.java | 11 ++++++++++- .../spring/status/SpringStatusCheckerTest.java | 13 ++++++++++++- 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java index 28592394149..4a73082ac6f 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java @@ -56,8 +56,6 @@ public class ServiceBean extends ServiceConfig implements InitializingBean private static final long serialVersionUID = 213195494150089726L; - private static transient ApplicationContext SPRING_CONTEXT; - private final transient Service service; private transient ApplicationContext applicationContext; @@ -78,10 +76,6 @@ public ServiceBean(Service service) { this.service = service; } - public static ApplicationContext getSpringContext() { - return SPRING_CONTEXT; - } - @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java index 5735ef35d74..5cbc06e35af 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java @@ -51,6 +51,10 @@ public static void removeApplicationContext(ApplicationContext context) { contexts.remove(context); } + public static Set getContexts() { + return contexts; + } + // currently for test purpose public static void clearContexts() { contexts.clear(); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java index fd0e32ded7f..32baa41da48 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java @@ -21,8 +21,8 @@ import com.alibaba.dubbo.common.logger.LoggerFactory; import com.alibaba.dubbo.common.status.Status; import com.alibaba.dubbo.common.status.StatusChecker; -import com.alibaba.dubbo.config.spring.ServiceBean; +import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; import org.springframework.context.ApplicationContext; import javax.sql.DataSource; @@ -42,7 +42,13 @@ public class DataSourceStatusChecker implements StatusChecker { @Override @SuppressWarnings("unchecked") public Status check() { - ApplicationContext context = ServiceBean.getSpringContext(); + ApplicationContext context = null; + for (ApplicationContext c : SpringExtensionFactory.getContexts()) { + if (c != null) { + context = c; + break; + } + } if (context == null) { return new Status(Status.Level.UNKNOWN); } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java index f722c913e7c..f80b5e6b806 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java @@ -21,8 +21,8 @@ import com.alibaba.dubbo.common.logger.LoggerFactory; import com.alibaba.dubbo.common.status.Status; import com.alibaba.dubbo.common.status.StatusChecker; -import com.alibaba.dubbo.config.spring.ServiceBean; +import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.Lifecycle; @@ -38,7 +38,13 @@ public class SpringStatusChecker implements StatusChecker { @Override public Status check() { - ApplicationContext context = ServiceBean.getSpringContext(); + ApplicationContext context = null; + for (ApplicationContext c : SpringExtensionFactory.getContexts()) { + if (c != null) { + context = c; + break; + } + } if (context == null) { return new Status(Status.Level.UNKNOWN); } diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusCheckerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusCheckerTest.java index 178f32c5deb..264a843043c 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusCheckerTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusCheckerTest.java @@ -19,10 +19,13 @@ import com.alibaba.dubbo.common.status.Status; import com.alibaba.dubbo.config.spring.ServiceBean; +import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Answers; import org.mockito.Mock; +import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import javax.sql.DataSource; @@ -47,11 +50,17 @@ public class DataSourceStatusCheckerTest { @Before public void setUp() throws Exception { + SpringExtensionFactory.clearContexts(); initMocks(this); this.dataSourceStatusChecker = new DataSourceStatusChecker(); new ServiceBean().setApplicationContext(applicationContext); } + @After + public void tearDown() throws Exception { + Mockito.reset(applicationContext); + } + @Test public void testWithoutApplicationContext() { Status status = dataSourceStatusChecker.check(); @@ -98,4 +107,4 @@ public void testWithDatasourceNotHasNextResult() throws SQLException { assertThat(status.getLevel(), is(Status.Level.ERROR)); } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/SpringStatusCheckerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/SpringStatusCheckerTest.java index 39f91257246..cc9038880b5 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/SpringStatusCheckerTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/status/SpringStatusCheckerTest.java @@ -19,9 +19,12 @@ import com.alibaba.dubbo.common.status.Status; import com.alibaba.dubbo.config.spring.ServiceBean; +import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; +import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.springframework.context.Lifecycle; @@ -44,6 +47,12 @@ public void setUp() throws Exception { new ServiceBean().setApplicationContext(applicationContext); } + @After + public void tearDown() throws Exception { + SpringExtensionFactory.clearContexts(); + Mockito.reset(applicationContext); + } + @Test public void testWithoutApplicationContext() { Status status = springStatusChecker.check(); @@ -53,6 +62,7 @@ public void testWithoutApplicationContext() { @Test public void testWithLifeCycleRunning() { + SpringExtensionFactory.clearContexts(); ApplicationLifeCycle applicationLifeCycle = mock(ApplicationLifeCycle.class); new ServiceBean().setApplicationContext(applicationLifeCycle); given(applicationLifeCycle.getConfigLocations()).willReturn(new String[]{"test1", "test2"}); @@ -66,6 +76,7 @@ public void testWithLifeCycleRunning() { @Test public void testWithoutLifeCycleRunning() { + SpringExtensionFactory.clearContexts(); ApplicationLifeCycle applicationLifeCycle = mock(ApplicationLifeCycle.class); new ServiceBean().setApplicationContext(applicationLifeCycle); given(applicationLifeCycle.isRunning()).willReturn(false); @@ -78,4 +89,4 @@ public void testWithoutLifeCycleRunning() { interface ApplicationLifeCycle extends Lifecycle, ApplicationContext { String[] getConfigLocations(); } -} \ No newline at end of file +}