├── jenvrc ├── spring-boot-starter-dubbo ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ ├── spring.provides │ │ │ ├── dubbo │ │ │ ├── com.alibaba.dubbo.rpc.ExporterListener │ │ │ ├── com.alibaba.dubbo.rpc.InvokerListener │ │ │ └── com.alibaba.dubbo.rpc.Filter │ │ │ ├── spring.factories │ │ │ └── additional-spring-configuration-metadata.json │ │ └── java │ │ └── org │ │ └── mvnsearch │ │ └── spring │ │ └── boot │ │ └── dubbo │ │ ├── EnableDubboConfiguration.java │ │ ├── listener │ │ ├── ProviderInvokeStaticsFilter.java │ │ ├── ConsumerInvokeStaticsFilter.java │ │ ├── StaticsFilter.java │ │ ├── ProviderExportListener.java │ │ └── ConsumerSubscribeListener.java │ │ ├── DubboBasedAutoConfiguration.java │ │ ├── DubboConsumerBuilder.java │ │ ├── DubboMetrics.java │ │ ├── DubboHealthIndicator.java │ │ ├── DubboOperationEndpoint.java │ │ ├── DubboProperties.java │ │ ├── DubboAutoConfiguration.java │ │ ├── DubboConsumerAutoConfiguration.java │ │ ├── DubboEndpoint.java │ │ └── DubboProviderAutoConfiguration.java ├── pom.xml └── README.md ├── spring-boot-starter-demo-uic ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ ├── spring.provides │ │ │ └── spring.factories │ │ └── java │ │ └── org │ │ └── mvnsearch │ │ └── uic │ │ └── boot │ │ ├── UicProperties.java │ │ └── UicDemoAutoconfiguration.java └── pom.xml ├── spring-boot-dubbo-client ├── src │ ├── main │ │ ├── resources │ │ │ ├── META-INF │ │ │ │ └── spring-devtools.properties │ │ │ ├── application.properties │ │ │ └── templates │ │ │ │ └── index.html │ │ └── java │ │ │ └── org │ │ │ └── mvnsearch │ │ │ ├── SpringBootDubboClientApplication.java │ │ │ └── PortalController.java │ └── test │ │ └── java │ │ └── org │ │ └── mvnsearch │ │ └── SpringBootDubboClientApplicationTests.java └── pom.xml ├── spring-boot-dubbo-server ├── src │ ├── main │ │ ├── resources │ │ │ ├── META-INF │ │ │ │ └── spring-devtools.properties │ │ │ ├── application.properties │ │ │ └── application-docker.properties │ │ └── java │ │ │ └── org │ │ │ └── mvnsearch │ │ │ └── uic │ │ │ ├── SpringBootDubboServerApplication.java │ │ │ ├── AccountManagerImpl.java │ │ │ └── UicTemplateImpl.java │ └── test │ │ └── java │ │ └── org │ │ └── mvnsearch │ │ └── SpringBootDubboServerApplicationTests.java ├── Dockerfile └── pom.xml ├── uic-service-common ├── src │ └── main │ │ └── java │ │ └── org │ │ └── mvnsearch │ │ └── uic │ │ ├── AccountManager.java │ │ ├── UicTemplate.java │ │ └── User.java └── pom.xml ├── docker-compose.yml ├── .gitignore ├── pom.xml └── README.md /jenvrc: -------------------------------------------------------------------------------- 1 | java=1.8.0_60 2 | maven=3.3.3-mvnsearch 3 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/spring.provides: -------------------------------------------------------------------------------- 1 | provides: spring-boot-starter-dubbo -------------------------------------------------------------------------------- /spring-boot-starter-demo-uic/src/main/resources/META-INF/spring.provides: -------------------------------------------------------------------------------- 1 | provides: spring-boot-starter-demo-uic -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/main/resources/META-INF/spring-devtools.properties: -------------------------------------------------------------------------------- 1 | restart.exclude.target-classes=/target/classes/ 2 | 3 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/resources/META-INF/spring-devtools.properties: -------------------------------------------------------------------------------- 1 | restart.exclude.target-classes=/target/classes/ 2 | 3 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.ExporterListener: -------------------------------------------------------------------------------- 1 | dubboexport=org.mvnsearch.spring.boot.dubbo.listener.ProviderExportListener -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.InvokerListener: -------------------------------------------------------------------------------- 1 | dubbosubscribe=org.mvnsearch.spring.boot.dubbo.listener.ConsumerSubscribeListener -------------------------------------------------------------------------------- /spring-boot-starter-demo-uic/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.mvnsearch.uic.boot.UicDemoAutoconfiguration -------------------------------------------------------------------------------- /spring-boot-dubbo-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | ADD target/spring-boot-dubbo-server-1.0.0-SNAPSHOT.jar /application.jar 4 | 5 | CMD java -jar /application.jar --spring.profiles.active=docker -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter: -------------------------------------------------------------------------------- 1 | dubboconsumerstatics=org.mvnsearch.spring.boot.dubbo.listener.ConsumerInvokeStaticsFilter 2 | dubboproviderstatics=org.mvnsearch.spring.boot.dubbo.listener.ProviderInvokeStaticsFilter -------------------------------------------------------------------------------- /uic-service-common/src/main/java/org/mvnsearch/uic/AccountManager.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | /** 4 | * account manager 5 | * 6 | * @author linux_china 7 | */ 8 | public interface AccountManager { 9 | 10 | public User findById(Long id); 11 | 12 | public void create(User user); 13 | } 14 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.mvnsearch.spring.boot.dubbo.DubboAutoConfiguration,\ 3 | org.mvnsearch.spring.boot.dubbo.DubboProviderAutoConfiguration,\ 4 | org.mvnsearch.spring.boot.dubbo.DubboConsumerAutoConfiguration -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=2080 2 | spring.application.name=dubbo-uic-consumer 3 | 4 | ### dubbo 5 | spring.dubbo.registry = redis://localhost:6379 6 | #spring.dubbo.registry = zookeeper://127.0.0.1:2181 7 | #spring.dubbo.registry = consul://127.0.0.1:8500 8 | 9 | ### ops 10 | spring.thymeleaf.cache=false -------------------------------------------------------------------------------- /uic-service-common/src/main/java/org/mvnsearch/uic/UicTemplate.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | import java.util.Optional; 4 | 5 | /** 6 | * uic template 7 | * 8 | * @author linux_china 9 | */ 10 | public interface UicTemplate { 11 | 12 | public User findById(Long id); 13 | 14 | Optional isEmailUnique(String email); 15 | } 16 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=20881 2 | spring.application.name=dubbo-uic-provider 3 | 4 | spring.dubbo.registry = redis://localhost:6379 5 | #spring.dubbo.registry = zookeeper://127.0.0.1:2181 6 | #spring.dubbo.registry = consul://127.0.0.1:8500 7 | #spring.dubbo.port= 20880 8 | 9 | spring.devtools.livereload.enabled=false -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Welcome 10 | Customer 11 | 12 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hints": [ 3 | { 4 | "name": "spring.dubbo.protocol", 5 | "values": [ 6 | { 7 | "value": "dubbo", 8 | "description": "Dubbo协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。" 9 | } 10 | ] 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/resources/application-docker.properties: -------------------------------------------------------------------------------- 1 | server.port=20881 2 | 3 | spring.dubbo.app = dubbo-uic-provider 4 | #spring.dubbo.registry = redis://localhost:6379 5 | spring.dubbo.registry = zookeeper://${ZK_HOST}:2181 6 | spring.dubbo.protocol = dubbo 7 | spring.dubbo.port= 20880 8 | spring.dubbo.exportHost=${EXPORT_HOST} 9 | spring.dubbo.exportPort=${EXPORT_PORT} 10 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | redis: 4 | image: redis:4.0.0-alpine 5 | ports: 6 | - "6379:6379" 7 | consul: 8 | image: consul:0.9.0 9 | ports: 10 | - "8300:8300" 11 | - "8301:8301" 12 | - "8302:8302" 13 | - "8400:8400" 14 | - "8500:8500" 15 | - "8600:53/udp" 16 | zookeeper: 17 | image: jplock/zookeeper 18 | ports: 19 | - "2181:2181" 20 | - "2888:2888" 21 | - "3888:3888" 22 | -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/test/java/org/mvnsearch/SpringBootDubboClientApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootDubboClientApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/test/java/org/mvnsearch/SpringBootDubboServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootDubboServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/EnableDubboConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * eanble dubbo configuration 7 | * 8 | * @author linux_china 9 | */ 10 | @Target(ElementType.TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | @Inherited 14 | public @interface EnableDubboConfiguration { 15 | /** 16 | * scan package for dubbo 17 | */ 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/main/java/org/mvnsearch/SpringBootDubboClientApplication.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ImportResource; 6 | 7 | @SpringBootApplication 8 | public class SpringBootDubboClientApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDubboClientApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/java/org/mvnsearch/uic/SpringBootDubboServerApplication.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | import org.mvnsearch.spring.boot.dubbo.EnableDubboConfiguration; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @EnableDubboConfiguration 9 | public class SpringBootDubboServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringBootDubboServerApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/java/org/mvnsearch/uic/AccountManagerImpl.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | import com.alibaba.dubbo.config.annotation.DubboService; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * account manager implementation 8 | * 9 | * @author linux_china 10 | */ 11 | @Component 12 | @DubboService(interfaceClass = AccountManager.class) 13 | public class AccountManagerImpl implements AccountManager { 14 | public User findById(Long id) { 15 | User user = new User(); 16 | user.setId(id); 17 | user.setNick("account:" + id); 18 | return user; 19 | } 20 | 21 | public void create(User user) { 22 | // 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/src/main/java/org/mvnsearch/uic/UicTemplateImpl.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | import com.alibaba.dubbo.config.annotation.DubboService; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.Date; 7 | import java.util.Optional; 8 | 9 | /** 10 | * uic template implementation 11 | * 12 | * @author linux_china 13 | */ 14 | @Component 15 | @DubboService(interfaceClass = UicTemplate.class) 16 | public class UicTemplateImpl implements UicTemplate { 17 | public User findById(Long id) { 18 | User user = new User(); 19 | user.setId(id); 20 | user.setNick("nick:" + id); 21 | user.setCreatedAt(new Date()); 22 | return user; 23 | } 24 | 25 | public Optional isEmailUnique(String email) { 26 | return Optional.of(1L); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spring-boot-dubbo-client/src/main/java/org/mvnsearch/PortalController.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch; 2 | 3 | import org.mvnsearch.uic.AccountManager; 4 | import org.mvnsearch.uic.UicTemplate; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | 10 | /** 11 | * portal controller 12 | * 13 | * @author linux_china 14 | */ 15 | @Controller 16 | public class PortalController { 17 | @Autowired 18 | private UicTemplate uicTemplate; 19 | @Autowired 20 | private AccountManager accountManager; 21 | 22 | @RequestMapping("/") 23 | public String index(Model model) { 24 | model.addAttribute("user", uicTemplate.findById(1L)); 25 | return "index"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /uic-service-common/src/main/java/org/mvnsearch/uic/User.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * user 8 | * 9 | * @author linux_china 10 | */ 11 | public class User implements Serializable { 12 | private Long id; 13 | private String nick; 14 | private Date createdAt; 15 | 16 | public Long getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public String getNick() { 25 | return nick; 26 | } 27 | 28 | public void setNick(String nick) { 29 | this.nick = nick; 30 | } 31 | 32 | public Date getCreatedAt() { 33 | return createdAt; 34 | } 35 | 36 | public void setCreatedAt(Date createdAt) { 37 | this.createdAt = createdAt; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spring-boot-starter-demo-uic/src/main/java/org/mvnsearch/uic/boot/UicProperties.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic.boot; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * uic properties 7 | * 8 | * @author linux_china 9 | */ 10 | @ConfigurationProperties(prefix = "spring.uic") 11 | public class UicProperties { 12 | /** 13 | * dubbo服务版本号,默认值为空 14 | */ 15 | private String version = ""; 16 | /** 17 | * rpc服务调用超时时间 18 | */ 19 | private Integer timeout = 3000; 20 | 21 | public String getVersion() { 22 | return version; 23 | } 24 | 25 | public void setVersion(String version) { 26 | this.version = version; 27 | } 28 | 29 | public Integer getTimeout() { 30 | return timeout; 31 | } 32 | 33 | public void setTimeout(Integer timeout) { 34 | this.timeout = timeout; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/listener/ProviderInvokeStaticsFilter.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo.listener; 2 | 3 | import com.alibaba.dubbo.common.Constants; 4 | import com.alibaba.dubbo.common.extension.Activate; 5 | import com.alibaba.dubbo.rpc.Invocation; 6 | import com.alibaba.dubbo.rpc.Invoker; 7 | import com.alibaba.dubbo.rpc.Result; 8 | import com.alibaba.dubbo.rpc.RpcException; 9 | 10 | /** 11 | * provider invoke statics filter 12 | * 13 | * @author linux_china 14 | */ 15 | @Activate(group = Constants.PROVIDER) 16 | public class ProviderInvokeStaticsFilter extends StaticsFilter { 17 | 18 | @SuppressWarnings("Duplicates") 19 | public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { 20 | increase(invoker.getInterface(), invocation.getMethodName()); 21 | return invoker.invoke(invocation); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/listener/ConsumerInvokeStaticsFilter.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo.listener; 2 | 3 | import com.alibaba.dubbo.common.Constants; 4 | import com.alibaba.dubbo.common.extension.Activate; 5 | import com.alibaba.dubbo.rpc.Invocation; 6 | import com.alibaba.dubbo.rpc.Invoker; 7 | import com.alibaba.dubbo.rpc.Result; 8 | import com.alibaba.dubbo.rpc.RpcException; 9 | 10 | import java.util.Map; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | import java.util.concurrent.atomic.AtomicLong; 13 | 14 | /** 15 | * consumer invoke statics filter 16 | * 17 | * @author linux_china 18 | */ 19 | @Activate(group = Constants.CONSUMER, order = -110000) 20 | public class ConsumerInvokeStaticsFilter extends StaticsFilter { 21 | public static Map statics = new ConcurrentHashMap<>(); 22 | 23 | public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { 24 | increase(invocation.getClass(), invocation.getMethodName()); 25 | return invoker.invoke(invocation); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/listener/StaticsFilter.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo.listener; 2 | 3 | import com.alibaba.dubbo.rpc.Filter; 4 | 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.atomic.AtomicLong; 8 | 9 | /** 10 | * statics filter 11 | * 12 | * @author linux_china 13 | */ 14 | public abstract class StaticsFilter implements Filter { 15 | public static Map statics = new ConcurrentHashMap(); 16 | 17 | public static void increase(Class clazz, String methodName) { 18 | String key = clazz.getCanonicalName() + "." + methodName; 19 | if (!statics.containsKey(key)) { 20 | statics.put(key, new AtomicLong(0)); 21 | } 22 | statics.get(key).incrementAndGet(); 23 | } 24 | 25 | public static long getValue(Class clazz, String methodName) { 26 | String key = clazz.getCanonicalName() + "." + methodName; 27 | AtomicLong value = statics.get(key); 28 | return value != null ? value.get() : 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboBasedAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.config.spring.ReferenceBean; 4 | import org.springframework.beans.BeansException; 5 | 6 | /** 7 | * dubbo based auto configuration 8 | * 9 | * @author linux_china 10 | */ 11 | public class DubboBasedAutoConfiguration { 12 | 13 | /** 14 | * 生成Dubbo的reference bean 15 | * 16 | * @param interfaceClazz interface class 17 | * @param version 版本号 18 | * @param timeout 超时时间 19 | * @param 服务接口 20 | * @return reference bean 21 | * @throws BeansException bean exception 22 | */ 23 | protected ReferenceBean getConsumerBean(Class interfaceClazz, String version, Integer timeout) throws BeansException { 24 | ReferenceBean consumerBean = new ReferenceBean(); 25 | String canonicalName = interfaceClazz.getCanonicalName(); 26 | consumerBean.setInterface(canonicalName); 27 | consumerBean.setId(canonicalName); 28 | consumerBean.setVersion(version); 29 | consumerBean.setTimeout(timeout); 30 | return consumerBean; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /uic-service-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | org.mvnsearch 7 | uic-service-common 8 | 1.0.0-SNAPSHOT 9 | uic-service-common 10 | 11 | UTF-8 12 | 13 | 14 | 15 | junit 16 | junit 17 | 4.12 18 | test 19 | 20 | 21 | 22 | 23 | 24 | 25 | maven-compiler-plugin 26 | 3.6.0 27 | 28 | 1.8 29 | 1.8 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboConsumerBuilder.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.config.spring.ReferenceBean; 4 | 5 | /** 6 | * dubbo consumer builder 7 | * 8 | * @author linux_china 9 | */ 10 | public class DubboConsumerBuilder { 11 | private Class interfaceClazz; 12 | private String version; 13 | private Integer timeout; 14 | 15 | public static DubboConsumerBuilder create() { 16 | return new DubboConsumerBuilder(); 17 | } 18 | 19 | public DubboConsumerBuilder service(Class interfaceClazz) { 20 | this.interfaceClazz = interfaceClazz; 21 | return this; 22 | } 23 | 24 | public DubboConsumerBuilder version(String version) { 25 | this.version = version; 26 | return this; 27 | } 28 | 29 | public DubboConsumerBuilder timeout(Integer timeout) { 30 | this.timeout = timeout; 31 | return this; 32 | } 33 | 34 | public ReferenceBean build() { 35 | ReferenceBean consumerBean = new ReferenceBean(); 36 | String canonicalName = interfaceClazz.getCanonicalName(); 37 | consumerBean.setInterface(canonicalName); 38 | consumerBean.setId(canonicalName); 39 | consumerBean.setVersion(version); 40 | consumerBean.setTimeout(timeout); 41 | return consumerBean; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 4 | 5 | *.iml 6 | 7 | ## Directory-based project format: 8 | .idea/ 9 | # if you remove the above rule, at least ignore the following: 10 | 11 | # User-specific stuff: 12 | # .idea/workspace.xml 13 | # .idea/tasks.xml 14 | # .idea/dictionaries 15 | 16 | # Sensitive or high-churn files: 17 | # .idea/dataSources.ids 18 | # .idea/dataSources.xml 19 | # .idea/sqlDataSources.xml 20 | # .idea/dynamic.xml 21 | # .idea/uiDesigner.xml 22 | 23 | # Gradle: 24 | # .idea/gradle.xml 25 | # .idea/libraries 26 | 27 | # Mongo Explorer plugin: 28 | # .idea/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.ipr 32 | *.iws 33 | 34 | ## Plugin-specific files: 35 | 36 | # IntelliJ 37 | /out/ 38 | 39 | # mpeltonen/sbt-idea plugin 40 | .idea_modules/ 41 | 42 | # JIRA plugin 43 | atlassian-ide-plugin.xml 44 | 45 | # Crashlytics plugin (for Android Studio and IntelliJ) 46 | com_crashlytics_export_strings.xml 47 | crashlytics.properties 48 | crashlytics-build.properties 49 | ### Java template 50 | *.class 51 | 52 | # Mobile Tools for Java (J2ME) 53 | .mtj.tmp/ 54 | 55 | # Package Files # 56 | *.jar 57 | *.war 58 | *.ear 59 | 60 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 61 | hs_err_pid* 62 | 63 | target/ -------------------------------------------------------------------------------- /spring-boot-starter-demo-uic/src/main/java/org/mvnsearch/uic/boot/UicDemoAutoconfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.uic.boot; 2 | 3 | import com.alibaba.dubbo.config.spring.ReferenceBean; 4 | import org.mvnsearch.spring.boot.dubbo.DubboAutoConfiguration; 5 | import org.mvnsearch.spring.boot.dubbo.DubboBasedAutoConfiguration; 6 | import org.mvnsearch.uic.AccountManager; 7 | import org.mvnsearch.uic.UicTemplate; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 10 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | 14 | /** 15 | * uic auto configuration 16 | * 17 | * @author linux_china 18 | */ 19 | @Configuration 20 | @EnableConfigurationProperties(UicProperties.class) 21 | @AutoConfigureAfter(DubboAutoConfiguration.class) 22 | public class UicDemoAutoconfiguration extends DubboBasedAutoConfiguration { 23 | @Autowired 24 | private UicProperties properties; 25 | 26 | @Bean 27 | public ReferenceBean uicTemplate() { 28 | return getConsumerBean(UicTemplate.class, properties.getVersion(), properties.getTimeout()); 29 | } 30 | 31 | @Bean 32 | public ReferenceBean accountManager() { 33 | return getConsumerBean(AccountManager.class, properties.getVersion(), properties.getTimeout()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboMetrics.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import org.mvnsearch.spring.boot.dubbo.listener.ConsumerInvokeStaticsFilter; 4 | import org.mvnsearch.spring.boot.dubbo.listener.ProviderInvokeStaticsFilter; 5 | import org.springframework.boot.actuate.endpoint.PublicMetrics; 6 | import org.springframework.boot.actuate.metrics.Metric; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Collection; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.concurrent.atomic.AtomicLong; 14 | 15 | /** 16 | * dubbo metrics 17 | * 18 | * @author linux_china 19 | */ 20 | @Component 21 | public class DubboMetrics implements PublicMetrics { 22 | public Collection> metrics() { 23 | List> metrics = new LinkedList>(); 24 | if (!ConsumerInvokeStaticsFilter.statics.isEmpty()) { 25 | for (Map.Entry entry : ConsumerInvokeStaticsFilter.statics.entrySet()) { 26 | metrics.add(new Metric("dubbo." + entry.getKey(), entry.getValue().get())); 27 | } 28 | } 29 | if (!ProviderInvokeStaticsFilter.statics.isEmpty()) { 30 | for (Map.Entry entry : ProviderInvokeStaticsFilter.statics.entrySet()) { 31 | metrics.add(new Metric("dubbo." + entry.getKey(), entry.getValue().get())); 32 | } 33 | } 34 | return metrics; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/listener/ProviderExportListener.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo.listener; 2 | 3 | import com.alibaba.dubbo.common.URL; 4 | import com.alibaba.dubbo.common.extension.Activate; 5 | import com.alibaba.dubbo.rpc.Exporter; 6 | import com.alibaba.dubbo.rpc.RpcException; 7 | import com.alibaba.dubbo.rpc.listener.ExporterListenerAdapter; 8 | 9 | import java.util.HashSet; 10 | import java.util.Set; 11 | 12 | /** 13 | * provider export listener 14 | * 15 | * @author linux_china 16 | */ 17 | @Activate 18 | public class ProviderExportListener extends ExporterListenerAdapter { 19 | /** 20 | * exported interfaces 21 | */ 22 | public static Set exportedInterfaces = new HashSet<>(); 23 | /** 24 | * exported urls 25 | */ 26 | public static Set exportedUrl = new HashSet<>(); 27 | 28 | public void exported(Exporter exporter) throws RpcException { 29 | Class anInterface = exporter.getInvoker().getInterface(); 30 | exportedInterfaces.add(anInterface); 31 | URL url = exporter.getInvoker().getUrl(); 32 | if (!url.getProtocol().equals("injvm")) { 33 | exportedUrl.add(url); 34 | } 35 | } 36 | 37 | public void unexported(Exporter exporter) { 38 | exportedInterfaces.remove(exporter.getInvoker().getInterface()); 39 | URL url = exporter.getInvoker().getUrl(); 40 | if (!url.getProtocol().equals("injvm")) { 41 | exportedUrl.remove(url); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboHealthIndicator.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.rpc.service.EchoService; 4 | import org.mvnsearch.spring.boot.dubbo.listener.ConsumerSubscribeListener; 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.boot.actuate.health.AbstractHealthIndicator; 7 | import org.springframework.boot.actuate.health.Health; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.ApplicationContextAware; 10 | import org.springframework.stereotype.Component; 11 | 12 | /** 13 | * dubbo health indicator 14 | * 15 | * @author linux_china 16 | */ 17 | @Component 18 | public class DubboHealthIndicator extends AbstractHealthIndicator implements ApplicationContextAware { 19 | private ApplicationContext applicationContext; 20 | 21 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 22 | this.applicationContext = applicationContext; 23 | } 24 | 25 | protected void doHealthCheck(Health.Builder builder) throws Exception { 26 | if (!ConsumerSubscribeListener.subscribedInterfaces.isEmpty()) { 27 | for (Class clazz : ConsumerSubscribeListener.subscribedInterfaces) { 28 | EchoService echoService = (EchoService) applicationContext.getBean(clazz); 29 | echoService.$echo("Hello"); 30 | builder.withDetail(clazz.getCanonicalName(), true); 31 | } 32 | } 33 | if (DubboOperationEndpoint.OFFLINE) { 34 | builder.down().withDetail("providers", "offline"); 35 | } else { 36 | builder.up(); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/listener/ConsumerSubscribeListener.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo.listener; 2 | 3 | import com.alibaba.dubbo.common.URL; 4 | import com.alibaba.dubbo.common.extension.Activate; 5 | import com.alibaba.dubbo.rpc.Invoker; 6 | import com.alibaba.dubbo.rpc.RpcException; 7 | import com.alibaba.dubbo.rpc.listener.InvokerListenerAdapter; 8 | 9 | import java.util.*; 10 | 11 | /** 12 | * dubbo client invoker listener 13 | * 14 | * @author linux_china 15 | */ 16 | @Activate 17 | public class ConsumerSubscribeListener extends InvokerListenerAdapter { 18 | public static Set subscribedInterfaces = new HashSet<>(); 19 | public static Map> connections = new HashMap<>(); 20 | 21 | @Override 22 | public void referred(Invoker invoker) throws RpcException { 23 | Class subscribeInterface = invoker.getInterface(); 24 | subscribedInterfaces.add(subscribeInterface); 25 | String subscribeInterfaceCanonicalName = subscribeInterface.getCanonicalName(); 26 | if (!connections.containsKey(subscribeInterfaceCanonicalName)) { 27 | connections.put(subscribeInterfaceCanonicalName, new HashSet<>()); 28 | } 29 | connections.get(subscribeInterfaceCanonicalName).add(invoker.getUrl().toString()); 30 | } 31 | 32 | @Override 33 | public void destroyed(Invoker invoker) { 34 | Class subscribedInterface = invoker.getInterface(); 35 | subscribedInterfaces.remove(subscribedInterface); 36 | String subscribedInterfaceCanonicalName = subscribedInterface.getCanonicalName(); 37 | if (connections.containsKey(subscribedInterfaceCanonicalName)) { 38 | connections.get(subscribedInterfaceCanonicalName).remove(invoker.getUrl().toString()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboOperationEndpoint.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.common.URL; 4 | import com.alibaba.dubbo.common.extension.ExtensionLoader; 5 | import com.alibaba.dubbo.config.ProtocolConfig; 6 | import com.alibaba.dubbo.registry.Registry; 7 | import com.alibaba.dubbo.registry.RegistryFactory; 8 | import org.mvnsearch.spring.boot.dubbo.listener.ProviderExportListener; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.actuate.endpoint.Endpoint; 11 | import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import javax.annotation.PostConstruct; 16 | 17 | /** 18 | * dubbo operation endpoint 19 | * 20 | * @author linux_china 21 | */ 22 | @RestController 23 | public class DubboOperationEndpoint implements MvcEndpoint { 24 | @Autowired 25 | private DubboProperties properties; 26 | private Registry registry; 27 | public static Boolean OFFLINE=false; 28 | 29 | @PostConstruct 30 | public void init() { 31 | ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(RegistryFactory.class); 32 | URL url = URL.valueOf(properties.getRegistry()); 33 | RegistryFactory registryFactory = extensionLoader.getExtension(url.getProtocol()); 34 | registry = registryFactory.getRegistry(url); 35 | } 36 | 37 | @RequestMapping("/offline") 38 | public String offline() { 39 | ProtocolConfig.destroyAll(); 40 | OFFLINE = true; 41 | return "sucess"; 42 | } 43 | 44 | public String getPath() { 45 | return "dubbo"; 46 | } 47 | 48 | public boolean isSensitive() { 49 | return false; 50 | } 51 | 52 | public Class getEndpointType() { 53 | return null; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | org.mvnsearch 6 | spring-boot-dubbo 7 | pom 8 | 1.0.0-SNAPSHOT 9 | Spring Boot with Dubbo 10 | 11 | uic-service-common 12 | spring-boot-dubbo-client 13 | spring-boot-dubbo-server 14 | spring-boot-starter-dubbo 15 | spring-boot-starter-demo-uic 16 | 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 4.3.18.RELEASE 22 | 1.5.14.RELEASE 23 | 24 | 25 | 26 | 27 | 28 | org.springframework 29 | spring-framework-bom 30 | ${spring.version} 31 | pom 32 | import 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-dependencies 37 | ${spring-boot.version} 38 | pom 39 | import 40 | 41 | 42 | io.spring.platform 43 | platform-bom 44 | Brussels-SR11 45 | pom 46 | import 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | maven-compiler-plugin 55 | 3.7.0 56 | 57 | 1.8 58 | 1.8 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /spring-boot-starter-demo-uic/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | spring-boot-dubbo 5 | org.mvnsearch 6 | 1.0.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | spring-boot-starter-demo-uic 11 | jar 12 | 13 | spring-boot-starter-demo-uic 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 1.3.0.RELEASE 19 | 20 | 21 | 22 | 23 | org.mvnsearch 24 | uic-service-common 25 | 1.0.0-SNAPSHOT 26 | 27 | 28 | org.mvnsearch.spring.boot 29 | spring-boot-starter-dubbo 30 | 1.0.0-SNAPSHOT 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-actuator 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-configuration-processor 39 | true 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | junit 48 | junit 49 | test 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | org.springframework.boot 59 | spring-boot-dependencies 60 | ${spring-boot.version} 61 | pom 62 | import 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spring Boot With Dubbo 2 | =========================== 3 | 主要介绍如何在Spring Boot中整合Dubbo的使用. 4 | 5 | ### 注意事项 6 | 7 | 由于Dubbo的版本并不是特别活跃,加上和Spring Boot的jar包适配等问题,所以请使用最新的Dubbo 3.0.0-SNAPSHOT版本, 目前还有很多工作调整 8 | 地址为: https://github.com/linux-china/dubbo3 9 | 10 | ### 注册中心(Registry) 11 | 目前主要是支持Redis、ZooKeeper和Consul这三个注册中心,主要是这两个服务非常普遍,同时由于Docker的流行,启动这三者个服务也非常简单。 12 | 13 | ##### Redis 14 | 使用Redis注册中心,需要将在pom.xml中添加对应的redis客户端,代码如下: 15 | 16 | ```xml 17 | 18 | redis.clients 19 | jedis 20 | 21 | ``` 22 | 23 | 对应的配置项为: spring.dubbo.registry = redis://localhost:6379 24 | 25 | ##### ZooKeeper 26 | 使用ZooKeeper注册中心,需要在pom.xml中添加zookeeper需要的jar包,代码如下: 27 | 28 | ```xml 29 | 30 | org.apache.curator 31 | curator-framework 32 | 2.12.0 33 | 34 | 35 | com.101tec 36 | zkclient 37 | 0.10 38 | 39 | ``` 40 | 41 | 对应的配置项为: spring.dubbo.registry = zookeeper://127.0.0.1:2181 42 | 43 | 多个zookeeper的配置项为: spring.dubbo.registry = zookeeper://192.168.0.2:2181,192.168.0.3:2181 44 | 45 | ### 如何测试 46 | 47 | * 首先使用IntelliJ IDEA导入项目 48 | * 调用docker-compose启动对应的注册中心: docker-compose up -d 49 | * 启动 SpringBootDubboServerApplication 50 | * 启动 SpringBootDubboClientApplication 51 | * 打开浏览器访问 http://localhost:2080 52 | 53 | ### 在 Docker 中运行 54 | 55 | * 调用docker-compose启动对应的注册中心: docker-compose up -d 56 | * 编译工程 `mvn clean package -Dmaven.test.skip` 57 | * 将 server 打包成 docker image : `docker build -t dubbo-demo:latest spring-boot-dubbo-server` 58 | * 运行 server (注意修改环境变量) : `docker run --rm --name=dubbo-demo -p 20890:20880 -e EXPORT_PORT=20890 -e EXPORT_HOST=YOUR_HOST_HERE -e ZK_HOST=YOUR_HOST_HERE dubbo-demo` 59 | * 启动 SpringBootDubboClientApplication 60 | * 打开浏览器访问 http://localhost:2080 61 | 62 | ### Spring DevTools注意事项 63 | 由于Spring DevTools采用不一样的classloader的机制,所以会导致Dubbo Consumer Bean无法赋值到指定的@Component上,请使用以下规则: 64 | 65 | 在 src/main/resources/META-INF/spring-devtools.properties 在添加以下代码进行DevTools的classloader屏蔽: 66 | ```properties 67 | restart.exclude.target-classes=/target/classes/ 68 | ``` 69 | 关于hotspot的模式下,相关Java代码调整后理解生效,可以考虑: http://dcevm.github.io/ 70 | 71 | 如果你的应用是纯Dubbo服务,没有涉及到Web页面,不建议你添加spring-devtools,如果添加了后, 72 | 可以通过以下配置项关闭livereload服务,这样可以保证不必要的live reload服务启动。 73 | ```properties 74 | spring.devtools.livereload.enabled=false 75 | ``` 76 | 77 | ### todo 78 | 79 | * DubboConsumerBuilder: 快速构建Dubbo Consumer 80 | * zipkin: https://github.com/jessyZu/dubbo-zipkin-spring-starter 81 | 82 | ### Spring Boot集成 83 | 84 | 请参看 [spring-boot-starter-dubbo](https://github.com/linux-china/spring-boot-dubbo/tree/master/spring-boot-starter-dubbo) 85 | 86 | -------------------------------------------------------------------------------- /spring-boot-dubbo-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.mvnsearch 7 | spring-boot-dubbo 8 | 1.0.0-SNAPSHOT 9 | 10 | spring-boot-dubbo-client 11 | 1.0.0-SNAPSHOT 12 | 13 | spring-boot-dubbo-client 14 | Spring Boot project with Dubbo client 15 | 16 | 17 | 18 | org.mvnsearch 19 | spring-boot-starter-demo-uic 20 | 1.0.0-SNAPSHOT 21 | 22 | 23 | org.mvnsearch.spring.boot 24 | spring-boot-starter-dubbo 25 | 1.0.0-SNAPSHOT 26 | 27 | 28 | org.apache.curator 29 | curator-framework 30 | 2.12.0 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-actuator 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-thymeleaf 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-devtools 47 | true 48 | 49 | 50 | redis.clients 51 | jedis 52 | 53 | 54 | com.ecwid.consul 55 | consul-api 56 | 1.2.3 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-test 61 | test 62 | 63 | 64 | 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-maven-plugin 70 | ${spring-boot.version} 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboProperties.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * dubbo properties 7 | * 8 | * @author linux_china 9 | */ 10 | @ConfigurationProperties(prefix = "spring.dubbo") 11 | public class DubboProperties { 12 | /** 13 | * dubbo application name 14 | */ 15 | private String app; 16 | /** 17 | * dubbo registry address 18 | */ 19 | private String registry; 20 | /** 21 | * dubbo monitor address 22 | */ 23 | private String monitor; 24 | /** 25 | * http check url 26 | */ 27 | private String httpCheckUrl; 28 | /** 29 | * communication protocol, default is dubbo 30 | */ 31 | private String protocol = "dubbo"; 32 | /** 33 | * transporter: netty 3 or netty 4 34 | */ 35 | private String transporter = "netty"; 36 | /** 37 | * dubbo listen port, default 20800 38 | */ 39 | private Integer port = 20800; 40 | /** 41 | * dubbo export host, useful when running in Docker 42 | */ 43 | private String exportHost; 44 | /** 45 | * dubbo export port, useful when running in Docker 46 | */ 47 | private Integer exportPort; 48 | /** 49 | * dubbo thread count, default 200 50 | */ 51 | private Integer threads = 200; 52 | 53 | public String getApp() { 54 | return app; 55 | } 56 | 57 | public void setApp(String app) { 58 | this.app = app; 59 | } 60 | 61 | public String getRegistry() { 62 | return registry; 63 | } 64 | 65 | public void setRegistry(String registry) { 66 | this.registry = registry; 67 | } 68 | 69 | public String getMonitor() { 70 | return monitor; 71 | } 72 | 73 | public void setMonitor(String monitor) { 74 | this.monitor = monitor; 75 | } 76 | 77 | public String getHttpCheckUrl() { 78 | return httpCheckUrl; 79 | } 80 | 81 | public void setHttpCheckUrl(String httpCheckUrl) { 82 | this.httpCheckUrl = httpCheckUrl; 83 | } 84 | 85 | public String getProtocol() { 86 | return protocol; 87 | } 88 | 89 | public void setProtocol(String protocol) { 90 | this.protocol = protocol; 91 | } 92 | 93 | public String getTransporter() { 94 | return transporter; 95 | } 96 | 97 | public void setTransporter(String transporter) { 98 | this.transporter = transporter; 99 | } 100 | 101 | public Integer getPort() { 102 | return port; 103 | } 104 | 105 | public void setPort(Integer port) { 106 | this.port = port; 107 | } 108 | 109 | public String getExportHost() { 110 | return exportHost; 111 | } 112 | 113 | public void setExportHost(String exportHost) { 114 | this.exportHost = exportHost; 115 | } 116 | 117 | public Integer getExportPort() { 118 | return exportPort; 119 | } 120 | 121 | public void setExportPort(Integer exportPort) { 122 | this.exportPort = exportPort; 123 | } 124 | 125 | public Integer getThreads() { 126 | return threads; 127 | } 128 | 129 | public void setThreads(Integer threads) { 130 | this.threads = threads; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /spring-boot-dubbo-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.mvnsearch 8 | spring-boot-dubbo 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | spring-boot-dubbo-server 13 | 1.0.0-SNAPSHOT 14 | 15 | spring-boot-dubbo-server 16 | Spring Boot app for dubbo server 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 22 | 23 | 24 | 25 | org.mvnsearch 26 | uic-service-common 27 | 1.0.0-SNAPSHOT 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | org.mvnsearch.spring.boot 39 | spring-boot-starter-dubbo 40 | 1.0.0-SNAPSHOT 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-devtools 45 | true 46 | 47 | 48 | redis.clients 49 | jedis 50 | 51 | 52 | com.ecwid.consul 53 | consul-api 54 | 1.4.0 55 | 56 | 57 | org.apache.curator 58 | curator-framework 59 | 2.12.0 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-test 64 | test 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | ${spring-boot.version} 74 | 75 | true 76 | 77 | 78 | 79 | 80 | repackage 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.config.ApplicationConfig; 4 | import com.alibaba.dubbo.config.MonitorConfig; 5 | import com.alibaba.dubbo.config.ProtocolConfig; 6 | import com.alibaba.dubbo.config.RegistryConfig; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 10 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.core.env.Environment; 14 | 15 | /** 16 | * dubbo auto configuration 17 | * 18 | * @author linux_china 19 | */ 20 | @Configuration 21 | @EnableConfigurationProperties(DubboProperties.class) 22 | public class DubboAutoConfiguration { 23 | @SuppressWarnings("SpringJavaAutowiringInspection") 24 | @Autowired 25 | private DubboProperties properties; 26 | @Autowired 27 | private Environment env; 28 | 29 | @Bean 30 | @ConditionalOnMissingBean 31 | public ApplicationConfig dubboApplicationConfig() { 32 | ApplicationConfig appConfig = new ApplicationConfig(); 33 | if (properties.getApp() == null || properties.getApp().isEmpty()) { 34 | properties.setApp(env.getProperty("spring.application.name")); 35 | } 36 | appConfig.setName(properties.getApp()); 37 | return appConfig; 38 | } 39 | 40 | @Bean 41 | @ConditionalOnMissingBean 42 | public ProtocolConfig dubboProtocolConfig() { 43 | ProtocolConfig protocolConfig = new ProtocolConfig(); 44 | protocolConfig.setName(properties.getProtocol()); 45 | protocolConfig.setTransporter(properties.getTransporter()); 46 | protocolConfig.setPort(properties.getPort()); 47 | protocolConfig.setExportHost(properties.getExportHost()); 48 | protocolConfig.setExportPort(properties.getExportPort()); 49 | protocolConfig.setThreads(properties.getThreads()); 50 | return protocolConfig; 51 | } 52 | 53 | @Bean 54 | @ConditionalOnMissingBean 55 | public RegistryConfig dubboRegistryConfig() { 56 | RegistryConfig registryConfig = new RegistryConfig(); 57 | registryConfig.setAddress(properties.getRegistry()); 58 | registryConfig.setCheck(true); 59 | return registryConfig; 60 | } 61 | 62 | @Bean 63 | @ConditionalOnMissingBean 64 | @ConditionalOnProperty(prefix = "spring.dubbo", name = "monitor") 65 | public MonitorConfig dubboMonitorConfig() { 66 | MonitorConfig monitorConfig = new MonitorConfig(); 67 | monitorConfig.setAddress(properties.getMonitor()); 68 | return monitorConfig; 69 | } 70 | 71 | @Bean 72 | public DubboOperationEndpoint dubboOperationEndpoint() { 73 | return new DubboOperationEndpoint(); 74 | } 75 | 76 | @Bean 77 | public DubboHealthIndicator dubboHealthIndicator() { 78 | return new DubboHealthIndicator(); 79 | } 80 | 81 | @Bean 82 | public DubboEndpoint dubboEndpoint() { 83 | return new DubboEndpoint(); 84 | } 85 | 86 | @Bean 87 | public DubboMetrics dubboConsumerMetrics() { 88 | return new DubboMetrics(); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | org.mvnsearch.spring.boot 7 | spring-boot-starter-dubbo 8 | 1.0.0-SNAPSHOT 9 | Spring Boot Starter for Dubbo 10 | 11 | UTF-8 12 | 1.8 13 | 1.5.3.RELEASE 14 | 15 | 16 | 17 | linux_china 18 | Jacky Chan 19 | libing.chen@gmail.com 20 | https://twitter.com/linux_china 21 | 22 | Developer 23 | 24 | 25 | 26 | 27 | scm:git:git@github.com:linux-china/spring-boot-dubbo.git 28 | scm:git:git@github.com:linux-china/spring-boot-dubbo.git 29 | https://github.com/linux-china/spring-boot-dubbo 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-actuator 35 | 36 | 37 | org.springframework 38 | spring-webmvc 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-configuration-processor 43 | true 44 | 45 | 46 | com.alibaba 47 | dubbo 48 | 3.0.0-SNAPSHOT 49 | 50 | 51 | junit 52 | junit 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 61 | org.springframework.boot 62 | spring-boot-dependencies 63 | ${spring-boot.version} 64 | pom 65 | import 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | maven-compiler-plugin 74 | 3.6.1 75 | 76 | 1.8 77 | 1.8 78 | 79 | 80 | 81 | 82 | 83 | 84 | mvnsearch_nexus 85 | mvnsearch nexus Releases 86 | http://nexus.mvnsearch.org/content/repositories/releases/ 87 | 88 | 89 | mvnsearch_nexus 90 | mvnsearch nexus Snapshots 91 | http://nexus.mvnsearch.org/content/repositories/snapshots/ 92 | 93 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboConsumerAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.config.ApplicationConfig; 4 | import com.alibaba.dubbo.config.ProtocolConfig; 5 | import com.alibaba.dubbo.config.RegistryConfig; 6 | import com.alibaba.dubbo.config.annotation.DubboConsumer; 7 | import com.alibaba.dubbo.config.spring.ReferenceBean; 8 | import com.fasterxml.jackson.core.Versioned; 9 | import org.springframework.beans.BeansException; 10 | import org.springframework.beans.factory.BeanCreationException; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.config.BeanPostProcessor; 13 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 14 | import org.springframework.context.ApplicationContext; 15 | import org.springframework.context.ApplicationContextAware; 16 | import org.springframework.context.annotation.Bean; 17 | import org.springframework.context.annotation.Configuration; 18 | 19 | import java.lang.reflect.Field; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * dubbo consumer auto configuration 25 | * 26 | * @author linux_china 27 | */ 28 | @SuppressWarnings("SpringJavaAutowiringInspection") 29 | @Configuration 30 | @AutoConfigureAfter(DubboAutoConfiguration.class) 31 | public class DubboConsumerAutoConfiguration extends DubboBasedAutoConfiguration implements ApplicationContextAware { 32 | private Map dubboReferences = new HashMap<>(); 33 | private ApplicationContext applicationContext; 34 | @Autowired 35 | private ApplicationConfig applicationConfig; 36 | @Autowired 37 | private RegistryConfig registryConfig; 38 | 39 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 40 | this.applicationContext = applicationContext; 41 | } 42 | 43 | @Bean 44 | public BeanPostProcessor beanPostProcessor() { 45 | return new BeanPostProcessor() { 46 | @Override 47 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 48 | Class objClz = bean.getClass(); 49 | if (org.springframework.aop.support.AopUtils.isAopProxy(bean)) { 50 | objClz = org.springframework.aop.support.AopUtils.getTargetClass(bean); 51 | } 52 | 53 | for (Field field : objClz.getDeclaredFields()) { 54 | DubboConsumer dubboConsumer = field.getAnnotation(DubboConsumer.class); 55 | if (dubboConsumer != null) { 56 | Class type = field.getType(); 57 | ReferenceBean consumerBean = getConsumerBean(type, dubboConsumer.version(), dubboConsumer.timeout()); 58 | String id = type.getCanonicalName() + ":" + dubboConsumer.version(); 59 | if (!dubboReferences.containsKey(id)) { 60 | consumerBean.setApplicationContext(applicationContext); 61 | consumerBean.setApplication(applicationConfig); 62 | consumerBean.setRegistry(registryConfig); 63 | consumerBean.setApplication(applicationConfig); 64 | try { 65 | consumerBean.afterPropertiesSet(); 66 | dubboReferences.put(id, consumerBean.getObject()); 67 | } catch (Exception e) { 68 | throw new BeanCreationException(beanName, e); 69 | } 70 | } 71 | try { 72 | field.setAccessible(true); 73 | field.set(bean, dubboReferences.get(id)); 74 | field.setAccessible(false); 75 | } catch (Exception e) { 76 | throw new BeanCreationException(beanName, e); 77 | } 78 | 79 | } 80 | } 81 | return bean; 82 | } 83 | 84 | @Override 85 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 86 | return bean; 87 | } 88 | }; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboEndpoint.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.config.annotation.DubboService; 4 | import org.mvnsearch.spring.boot.dubbo.listener.ConsumerInvokeStaticsFilter; 5 | import org.mvnsearch.spring.boot.dubbo.listener.ConsumerSubscribeListener; 6 | import org.mvnsearch.spring.boot.dubbo.listener.ProviderExportListener; 7 | import org.mvnsearch.spring.boot.dubbo.listener.ProviderInvokeStaticsFilter; 8 | import org.springframework.beans.BeansException; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.actuate.endpoint.AbstractEndpoint; 11 | import org.springframework.context.ApplicationContext; 12 | import org.springframework.context.ApplicationContextAware; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.util.ReflectionUtils; 15 | 16 | import java.lang.reflect.Method; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | import java.util.Set; 20 | 21 | /** 22 | * dubbo endpoint 23 | * 24 | * @author linux_china 25 | */ 26 | @Component 27 | public class DubboEndpoint extends AbstractEndpoint implements ApplicationContextAware { 28 | private DubboProperties dubboProperties; 29 | private ApplicationContext applicationContext; 30 | 31 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 32 | this.applicationContext = applicationContext; 33 | } 34 | 35 | @Autowired 36 | public void setDubboProperties(DubboProperties dubboProperties) { 37 | this.dubboProperties = dubboProperties; 38 | } 39 | 40 | public DubboEndpoint() { 41 | super("dubbo", false, true); 42 | } 43 | 44 | public Object invoke() { 45 | Map info = new HashMap(); 46 | Boolean serverMode = false; 47 | String[] beanNames = applicationContext.getBeanNamesForAnnotation(EnableDubboConfiguration.class); 48 | if (beanNames != null && beanNames.length > 0) { 49 | serverMode = true; 50 | } 51 | if (serverMode) { 52 | info.put("server", true); 53 | info.put("port", dubboProperties.getPort()); 54 | } 55 | info.put("app", dubboProperties.getApp()); 56 | info.put("registry", dubboProperties.getRegistry()); 57 | info.put("protocol", dubboProperties.getProtocol()); 58 | //published services 59 | Map> publishedInterfaceList = new HashMap>(); 60 | Set publishedInterfaces = ProviderExportListener.exportedInterfaces; 61 | for (Class clazz : publishedInterfaces) { 62 | String interfaceClassCanonicalName = clazz.getCanonicalName(); 63 | if (!interfaceClassCanonicalName.equals("void")) { 64 | Map methodNames = new HashMap(); 65 | for (Method method : clazz.getMethods()) { 66 | methodNames.put(method.getName(), ProviderInvokeStaticsFilter.getValue(clazz, method.getName())); 67 | } 68 | publishedInterfaceList.put(interfaceClassCanonicalName, methodNames); 69 | } 70 | } 71 | if (!publishedInterfaceList.isEmpty()) { 72 | info.put("publishedInterfaces", publishedInterfaceList); 73 | } 74 | //subscribed services 75 | Set subscribedInterfaces = ConsumerSubscribeListener.subscribedInterfaces; 76 | if (!subscribedInterfaces.isEmpty()) { 77 | try { 78 | Map> subscribedInterfaceList = new HashMap>(); 79 | for (Class clazz : subscribedInterfaces) { 80 | Map methodNames = new HashMap(); 81 | for (Method method : clazz.getMethods()) { 82 | methodNames.put(method.getName(), ConsumerInvokeStaticsFilter.getValue(clazz, method.getName())); 83 | } 84 | subscribedInterfaceList.put(clazz.getCanonicalName(), methodNames); 85 | } 86 | info.put("subscribedInterfaces", subscribedInterfaceList); 87 | } catch (Exception ignore) { 88 | 89 | } 90 | info.put("connections", ConsumerSubscribeListener.connections); 91 | } 92 | return info; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/README.md: -------------------------------------------------------------------------------- 1 | Spring Boot Start Dubbo 2 | ================================= 3 | 在Spring Boot中整合Dubbo服务发布. 4 | 5 | 6 | ### 如何发布Dubbo服务? 7 | 8 | * 首先在pom.xml中添加对spring-boot-starter-dubbo的引用 9 | 10 | 11 | 12 | org.mvnsearch.spring.boot 13 | spring-boot-starter-dubbo 14 | 1.0.0-SNAPSHOT 15 | 16 | 17 | * 在application.properties文件中添加相关的配置,如下: 18 | 19 | 20 | spring.dubbo.app = dubbo-uic-provider 21 | spring.dubbo.registry = redis://192.168.99.100:6379 22 | spring.dubbo.protocol = dubbo 23 | spring.dubbo.port= 20880 24 | 25 | * 然后在Spring Boot Application程序中添加 @EnableDubboConfiguration,样例代码如下: 26 | 27 | 28 | 29 | @SpringBootApplication 30 | @EnableDubboConfiguration() 31 | public class SpringBootDubboServerApplication 32 | 33 | 其中org.mvnsearch.uic是Dubbo要扫描的package,根据Dubbo的Service annotation发布服务. 34 | 35 | * 在Spring Bean上添加@DubboService Annotation进行Dubbo服务发布,代码如下: 36 | 37 | 38 | @Component 39 | @DubboService(interfaceClass = UicTemplate.class) 40 | public class UicTemplateImpl implements UicTemplate 41 | 42 | ### 客户端如何引用Dubbo服务 43 | 44 | 考虑到客户端的bean引用,目前还是采用spring boot配置和传统的Xml声明方式,也就是dubbo的配置是配置的,dubbo beans是xml引用的方式. 45 | 46 | * 首先在pom.xml中添加对spring-boot-starter-dubbo的引用 47 | 48 | 49 | 50 | org.mvnsearch.spring.boot 51 | spring-boot-starter-dubbo 52 | 1.0.0-SNAPSHOT 53 | 54 | 55 | * 在application.properties文件中添加相关的配置,如下: 56 | 57 | 58 | spring.dubbo.app = dubbo-uic-consumer 59 | spring.dubbo.registry = redis://192.168.99.100:6379 60 | spring.dubbo.protocol = dubbo 61 | 62 | * 接下来你只需要创建一个ReferenceBean即可,代码如下。 这个也是Spring Boot推荐的做法。 63 | 64 | ``` 65 | @Bean 66 | public ReferenceBean uicTemplate() { 67 | return getConsumerBean(UicTemplate.class, properties.getVersion(), properties.getTimeout()); 68 | } 69 | ``` 70 | * 如果你不想创建上述的ReferenceBean,你也可以在在要引用的Dubbo Service Interface上添加 @DubboConsumer即可,代码如下: 71 | ``` 72 | @DubboConsumer 73 | private UicTemplate uicTemplate; 74 | ``` 75 | * 最后如果你还想用xml中声明 dubbo consumer beans的配置文件,样例如下: 76 | 77 | 78 | 79 | 80 | 85 | 86 | 87 | 88 | 89 | 90 | * 然后在Spring Boot Application中使用@ImportResource引入dubbo consumer xml文件,如下: 91 | 92 | 93 | @SpringBootApplication 94 | @ImportResource("/uic-dubbo-consumer.xml") 95 | public class SpringBootDubboClientApplication 96 | 97 | ### 优雅上下线 98 | 当我们要重新发布应用时候,我们需要新停掉服务,然后稍等一段时间,等客户端连接全部切换到其他服务器上,这个时候我们才能开始部署服务。这个就是我们称之为优雅下线, 99 | 目前可以通过 http://localhost:8080/dubbo/offline 100 | 101 | ### 其他 102 | 103 | * Dubbo Endpint: spring-boot-starter-dubbo提供了dubbo的enpoint,通过该url可以快速了解Dubbo的运行信息 104 | * health indicator: 对远程服务进行echo service调用进行health检查,通过 /health 进行查看 105 | 106 | ### 注意 107 | 108 | * 对应Dubbo服务端应用来说,在重新发布应用时需要调用 /dubbo/offline 首先进行应用下线,然后稍后15秒钟后进行发布. 109 | 110 | ### 第三方客户端整合 111 | 112 | 如果你要在第三方客户端,如uic-client,直接整合Dubbo服务对外提供相关的接口,可以使用Spring Boot和Dubbo结合,自动完成auto configuration, 113 | 如spring-boot-starter-uic-client代码中,引入spring-boot-starter-dubbo,然后在UicAutoConfiguration中进行Dubbo服务关联,代码如下: 114 | 115 | @Bean 116 | public ReferenceBean uicTemplate() { 117 | ReferenceBean referenceBean = new ReferenceBean(); 118 | String canonicalName = interfaceClazz.getCanonicalName(); 119 | referenceBean.setInterface(canonicalName); 120 | referenceBean.setId(canonicalName); 121 | referenceBean.setTimeout(10000); 122 | return referenceBean; 123 | } 124 | 这里一定要使用类的canonicalName方式初始化,主要是解决Dubbo ClassLoader和Spring Boot的class loader问题. 125 | 当然,你可能需要通过自定义properties方式来设置对应的版本号. 这样他人在引入spring-boot-starter-uic-client后就可以直接使用UicTemplate对应的服务啦. 126 | 127 | 128 | -------------------------------------------------------------------------------- /spring-boot-starter-dubbo/src/main/java/org/mvnsearch/spring/boot/dubbo/DubboProviderAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.mvnsearch.spring.boot.dubbo; 2 | 3 | import com.alibaba.dubbo.common.utils.NetUtils; 4 | import com.alibaba.dubbo.config.ApplicationConfig; 5 | import com.alibaba.dubbo.config.ProtocolConfig; 6 | import com.alibaba.dubbo.config.RegistryConfig; 7 | import com.alibaba.dubbo.config.annotation.DubboService; 8 | import com.alibaba.dubbo.config.spring.ServiceBean; 9 | import org.springframework.beans.BeansException; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties; 12 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 13 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 14 | import org.springframework.boot.autoconfigure.web.ServerProperties; 15 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 16 | import org.springframework.context.ApplicationContext; 17 | import org.springframework.context.ApplicationContextAware; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.core.env.Environment; 20 | 21 | import javax.annotation.PostConstruct; 22 | import java.net.InetAddress; 23 | import java.util.Map; 24 | 25 | /** 26 | * dubbo provider auto configuration 27 | * 28 | * @author linux_china 29 | */ 30 | @SuppressWarnings("SpringJavaAutowiringInspection") 31 | @Configuration 32 | @ConditionalOnBean(annotation = EnableDubboConfiguration.class) 33 | @AutoConfigureAfter(DubboAutoConfiguration.class) 34 | @EnableConfigurationProperties(DubboProperties.class) 35 | public class DubboProviderAutoConfiguration implements ApplicationContextAware { 36 | private ApplicationContext applicationContext; 37 | @Autowired 38 | private ApplicationConfig applicationConfig; 39 | @Autowired 40 | private ProtocolConfig protocolConfig; 41 | @Autowired 42 | private RegistryConfig registryConfig; 43 | @Autowired 44 | private DubboProperties dubboProperties; 45 | @Autowired 46 | private ManagementServerProperties managementServerProperties; 47 | @Autowired 48 | private ServerProperties serverProperties; 49 | 50 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 51 | this.applicationContext = applicationContext; 52 | } 53 | 54 | @PostConstruct 55 | public void init() throws Exception { 56 | if (dubboProperties.getHttpCheckUrl() != null) { 57 | System.setProperty("DUBBO_HTTP_CHECK_URL", dubboProperties.getHttpCheckUrl()); 58 | } else { 59 | String schema = managementServerProperties.getSsl() == null ? "http://" : "https://"; 60 | Integer managementPort = managementServerProperties.getPort() == null ? serverProperties.getPort() : managementServerProperties.getPort(); 61 | String managementHost; 62 | if (managementServerProperties.getAddress() != null) { 63 | managementHost = managementServerProperties.getAddress().getHostAddress(); 64 | } else if (serverProperties.getAddress() != null) { 65 | managementHost = serverProperties.getAddress().getHostAddress(); 66 | } else { 67 | managementHost = NetUtils.getLocalHost(); 68 | } 69 | String dubboHTTPCheckURL = schema + managementHost + ":" + managementPort + managementServerProperties.getContextPath() + "/health"; 70 | System.setProperty("DUBBO_HTTP_CHECK_URL", dubboHTTPCheckURL); 71 | } 72 | Map beans = applicationContext.getBeansWithAnnotation(DubboService.class); 73 | for (Map.Entry entry : beans.entrySet()) { 74 | publishDubboService(entry.getKey(), entry.getValue()); 75 | } 76 | } 77 | 78 | public void publishDubboService(String beanName, Object bean) throws Exception { 79 | DubboService service = applicationContext.findAnnotationOnBean(beanName, DubboService.class); 80 | ServiceBean serviceConfig = new ServiceBean(service); 81 | if (void.class.equals(service.interfaceClass()) 82 | && "".equals(service.interfaceName())) { 83 | if (bean.getClass().getInterfaces().length > 0) { 84 | serviceConfig.setInterface(bean.getClass().getInterfaces()[0]); 85 | } else { 86 | throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces."); 87 | } 88 | } 89 | serviceConfig.setApplicationContext(applicationContext); 90 | serviceConfig.setApplication(applicationConfig); 91 | serviceConfig.setProtocol(protocolConfig); 92 | serviceConfig.setRegistry(registryConfig); 93 | serviceConfig.afterPropertiesSet(); 94 | serviceConfig.setRef(bean); 95 | serviceConfig.export(); 96 | } 97 | 98 | } 99 | --------------------------------------------------------------------------------