You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/12/18 02:45:15 UTC
[dubbo] branch 2.7.5-release updated: [Dubbo-5495] Services can't
be exported for projects driven by annotation but with
EnableDubbo/EnableDubboLifecycle not enabled (#5496)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 2.7.5-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/2.7.5-release by this push:
new a5b8a87 [Dubbo-5495] Services can't be exported for projects driven by annotation but with EnableDubbo/EnableDubboLifecycle not enabled (#5496)
a5b8a87 is described below
commit a5b8a870136c0ce6c8a2c4bed74ec7f9f6cf62f6
Author: Mercy Ma <me...@gmail.com>
AuthorDate: Wed Dec 18 10:44:58 2019 +0800
[Dubbo-5495] Services can't be exported for projects driven by annotation but with EnableDubbo/EnableDubboLifecycle not enabled (#5496)
Fixes #5495
---
.../ServiceAnnotationBeanPostProcessor.java | 11 +++-
.../context/DubboBootstrapApplicationListener.java | 63 +++++++++++++++++++
...DubboLifecycleComponentApplicationListener.java | 60 +++++++-----------
...meExecutionApplicationContextEventListener.java | 71 ++++++++++++++++++++++
.../DubboLifecycleComponentRegistrar.java | 2 +
.../beans/factory/ServiceBeanPostProcessor.java | 37 -----------
.../ServiceAnnotationTestConfiguration.java | 6 --
.../spring/context/annotation/EnableDubboTest.java | 6 --
.../annotation/provider/ProviderConfiguration.java | 6 --
9 files changed, 167 insertions(+), 95 deletions(-)
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index c96f7b9..08a0965 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ServiceBean;
+import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener;
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
import org.springframework.beans.BeansException;
@@ -63,6 +64,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
import static com.alibaba.spring.util.ObjectUtils.of;
import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create;
import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveServiceInterfaceClass;
@@ -107,6 +109,9 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ // @since 2.7.5
+ registerBeans(registry, DubboBootstrapApplicationListener.class);
+
Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
@@ -456,10 +461,10 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
}
private List convertMethodConfigs(Object methodsAnnotation) {
- if (methodsAnnotation == null){
+ if (methodsAnnotation == null) {
return Collections.EMPTY_LIST;
}
- return MethodConfig.constructMethodConfig((Method[])methodsAnnotation);
+ return MethodConfig.constructMethodConfig((Method[]) methodsAnnotation);
}
private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) {
@@ -523,4 +528,4 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
this.classLoader = classLoader;
}
-}
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java
new file mode 100644
index 0000000..fd11690
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java
@@ -0,0 +1,63 @@
+/*
+ * 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.context;
+
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ApplicationContextEvent;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.Ordered;
+
+/**
+ * The {@link ApplicationListener} for {@link DubboBootstrap}'s lifecycle when the {@link ContextRefreshedEvent}
+ * and {@link ContextClosedEvent} raised
+ *
+ * @since 2.7.5
+ */
+public class DubboBootstrapApplicationListener extends OneTimeExecutionApplicationContextEventListener
+ implements Ordered {
+
+ private final DubboBootstrap dubboBootstrap;
+
+ public DubboBootstrapApplicationListener() {
+ this.dubboBootstrap = DubboBootstrap.getInstance();
+ }
+
+ @Override
+ public void onApplicationContextEvent(ApplicationContextEvent event) {
+ if (event instanceof ContextRefreshedEvent) {
+ onContextRefreshedEvent((ContextRefreshedEvent) event);
+ } else if (event instanceof ContextClosedEvent) {
+ onContextClosedEvent((ContextClosedEvent) event);
+ }
+ }
+
+ private void onContextRefreshedEvent(ContextRefreshedEvent event) {
+ dubboBootstrap.start();
+ }
+
+ private void onContextClosedEvent(ContextClosedEvent event) {
+ dubboBootstrap.stop();
+ }
+
+ @Override
+ public int getOrder() {
+ return LOWEST_PRECEDENCE;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboLifecycleComponentApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboLifecycleComponentApplicationListener.java
index 61cb66d..7aad776 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboLifecycleComponentApplicationListener.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboLifecycleComponentApplicationListener.java
@@ -18,20 +18,18 @@ package org.apache.dubbo.config.spring.context;
import org.apache.dubbo.common.context.Lifecycle;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.config.DubboShutdownHook;
-import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
-import java.util.Map;
+import java.util.LinkedList;
+import java.util.List;
+import static java.util.Collections.emptyList;
import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
/**
@@ -41,15 +39,12 @@ import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncl
* @see SmartApplicationListener
* @since 2.7.5
*/
-public class DubboLifecycleComponentApplicationListener implements ApplicationListener {
+public class DubboLifecycleComponentApplicationListener extends OneTimeExecutionApplicationContextEventListener {
- @Override
- public void onApplicationEvent(ApplicationEvent event) {
-
- if (!supportsEvent(event)) {
- return;
- }
+ private List<Lifecycle> lifecycleComponents = emptyList();
+ @Override
+ protected void onApplicationContextEvent(ApplicationContextEvent event) {
if (event instanceof ContextRefreshedEvent) {
onContextRefreshedEvent((ContextRefreshedEvent) event);
} else if (event instanceof ContextClosedEvent) {
@@ -58,40 +53,31 @@ public class DubboLifecycleComponentApplicationListener implements ApplicationLi
}
protected void onContextRefreshedEvent(ContextRefreshedEvent event) {
- ApplicationContext context = event.getApplicationContext();
- DubboBootstrap bootstrap = loadBootsttrapAsBean(context);
- if (bootstrap == null) {
- bootstrap = DubboBootstrap.getInstance();
- }
- bootstrap.start();
+ initLifecycleComponents(event);
+ startLifecycleComponents();
}
protected void onContextClosedEvent(ContextClosedEvent event) {
- DubboShutdownHook.getDubboShutdownHook().doDestroy();
+ destroyLifecycleComponents();
}
- private DubboBootstrap loadBootsttrapAsBean(ApplicationContext context) {
- Map<String, DubboBootstrap> beans = beansOfTypeIncludingAncestors(context, DubboBootstrap.class);
- if (CollectionUtils.isNotEmptyMap(beans)) {
- return beans.values().iterator().next();
- }
- return null;
+ private void initLifecycleComponents(ContextRefreshedEvent event) {
+ ApplicationContext context = event.getApplicationContext();
+ ClassLoader classLoader = context.getClassLoader();
+ lifecycleComponents = new LinkedList<>();
+ // load the Beans of Lifecycle from ApplicationContext
+ loadLifecycleComponents(lifecycleComponents, context);
}
- /**
- * the specified {@link ApplicationEvent event} must be {@link ApplicationContextEvent} and
- * its correlative {@link ApplicationContext} must be root
- *
- * @param event
- * @return
- */
- private boolean supportsEvent(ApplicationEvent event) {
- return event instanceof ApplicationContextEvent &&
- isRootApplicationContext((ApplicationContextEvent) event);
+ private void loadLifecycleComponents(List<Lifecycle> lifecycleComponents, ApplicationContext context) {
+ lifecycleComponents.addAll(beansOfTypeIncludingAncestors(context, Lifecycle.class).values());
}
+ private void startLifecycleComponents() {
+ lifecycleComponents.forEach(Lifecycle::start);
+ }
- private boolean isRootApplicationContext(ApplicationContextEvent event) {
- return event.getApplicationContext().getParent() == null;
+ private void destroyLifecycleComponents() {
+ lifecycleComponents.forEach(Lifecycle::destroy);
}
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/OneTimeExecutionApplicationContextEventListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/OneTimeExecutionApplicationContextEventListener.java
new file mode 100644
index 0000000..569a67e
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/OneTimeExecutionApplicationContextEventListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.context;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ApplicationContextEvent;
+
+import java.util.Objects;
+
+/**
+ * The abstract class {@link ApplicationListener} for {@link ApplicationContextEvent} guarantees just one-time execution
+ * and prevents the event propagation in the hierarchical {@link ApplicationContext ApplicationContexts}
+ *
+ * @since 2.7.5
+ */
+abstract class OneTimeExecutionApplicationContextEventListener implements ApplicationListener, ApplicationContextAware {
+
+ private ApplicationContext applicationContext;
+
+ public final void onApplicationEvent(ApplicationEvent event) {
+ if (isOriginalEventSource(event) && event instanceof ApplicationContextEvent) {
+ onApplicationContextEvent((ApplicationContextEvent) event);
+ }
+ }
+
+ /**
+ * The subclass overrides this method to handle {@link ApplicationContextEvent}
+ *
+ * @param event {@link ApplicationContextEvent}
+ */
+ protected abstract void onApplicationContextEvent(ApplicationContextEvent event);
+
+ /**
+ * Is original {@link ApplicationContext} as the event source
+ *
+ * @param event {@link ApplicationEvent}
+ * @return
+ */
+ private boolean isOriginalEventSource(ApplicationEvent event) {
+ return (applicationContext == null) // Current ApplicationListener is not a Spring Bean, just was added
+ // into Spring's ConfigurableApplicationContext
+ || Objects.equals(applicationContext, event.getSource());
+ }
+
+ @Override
+ public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
index c192c8d..20fd1a9 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
@@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.common.context.Lifecycle;
+import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener;
import org.apache.dubbo.config.spring.context.DubboLifecycleComponentApplicationListener;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -35,5 +36,6 @@ public class DubboLifecycleComponentRegistrar implements ImportBeanDefinitionReg
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registerBeans(registry, DubboLifecycleComponentApplicationListener.class);
+ registerBeans(registry, DubboBootstrapApplicationListener.class);
}
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/ServiceBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/ServiceBeanPostProcessor.java
deleted file mode 100644
index 52c7500..0000000
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/ServiceBeanPostProcessor.java
+++ /dev/null
@@ -1,37 +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.beans.factory;
-
-import org.apache.dubbo.config.spring.ServiceBean;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-
-public class ServiceBeanPostProcessor implements BeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof ServiceBean) {
- ((ServiceBean) bean).export();
- }
- return bean;
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration.java
index daa95aa..7a206db 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration.java
@@ -21,7 +21,6 @@ import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.annotation.Service;
-import org.apache.dubbo.config.spring.beans.factory.ServiceBeanPostProcessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@@ -86,11 +85,6 @@ public class ServiceAnnotationTestConfiguration {
return protocolConfig;
}
- @Bean
- public ServiceBeanPostProcessor serviceBeanPostProcessor() {
- return new ServiceBeanPostProcessor();
- }
-
@Primary
@Bean
public PlatformTransactionManager platformTransactionManager() {
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
index 54660b7..42fadfc 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.api.DemoService;
-import org.apache.dubbo.config.spring.beans.factory.ServiceBeanPostProcessor;
import org.apache.dubbo.config.spring.context.annotation.consumer.test.TestConsumerConfiguration;
import org.apache.dubbo.config.spring.context.annotation.provider.DemoServiceImpl;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -152,11 +151,6 @@ public class EnableDubboTest {
@EnableTransactionManagement
public static class TestProviderConfiguration {
- @Bean
- public ServiceBeanPostProcessor serviceBeanPostProcessor() {
- return new ServiceBeanPostProcessor();
- }
-
@Primary
@Bean
public PlatformTransactionManager platformTransactionManager() {
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/provider/ProviderConfiguration.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/provider/ProviderConfiguration.java
index b31e670..d168af8 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/provider/ProviderConfiguration.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/provider/ProviderConfiguration.java
@@ -19,7 +19,6 @@ package org.apache.dubbo.config.spring.context.annotation.provider;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
-import org.apache.dubbo.config.spring.beans.factory.ServiceBeanPostProcessor;
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.context.annotation.Bean;
@@ -82,11 +81,6 @@ public class ProviderConfiguration {
return protocolConfig;
}
- @Bean
- public ServiceBeanPostProcessor serviceBeanPostProcessor() {
- return new ServiceBeanPostProcessor();
- }
-
@Primary
@Bean
public PlatformTransactionManager platformTransactionManager() {