Closed onebyte0755 closed 7 years ago
实现起来并不复杂!我根据spring-boot-starter-dubbo-master 稍微改了一下! DubboHolderListener 观察ApplicationPreparedEvent事件
public class DubboHolderListener extends DubboApplicationName implements ApplicationListener<ApplicationEvent> {
private static final Logger LOG = LoggerFactory.getLogger(DubboHolderListener.class);
private long threadsleep = 10L;
private static AtomicBoolean running = new AtomicBoolean(false);
private static ExecutorService singleThreadExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
private volatile String applicationName = super.getApplicationName();
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationPreparedEvent) {
if (running.compareAndSet(false, true)) {
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
Thread.currentThread()
.setName(getcurrentThreadName(Thread.currentThread().getName(), applicationName));
if (LOG.isTraceEnabled()) {
LOG.trace("当前线程名称:{} ", Thread.currentThread().getName());
}
while (running.get()) {
try {
TimeUnit.SECONDS.sleep(threadsleep);
} catch (InterruptedException e) {
LOG.warn("SpringBootStarterDubbo service stopped,interrupted by other thread!", e);
}
}
}
});
}
}
if (event instanceof ContextClosedEvent) {
if (running.compareAndSet(true, false)) {
if (!singleThreadExecutor.isShutdown()) {
singleThreadExecutor.shutdown();
}
}
}
}
public static void closeApplicationContext(boolean stop) {
if (running.compareAndSet(true, false)) {
singleThreadExecutor.shutdown();
}
}
}
DubboApplicationName 获取当前应用名称
public class DubboApplicationName {
protected Class<?> sourceClass;
public Class<?> getSourceClass() {
return sourceClass;
}
public void setSourceClass(Class<?> sourceClass) {
this.sourceClass = sourceClass;
}
protected Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
} catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
protected String getApplicationName() {
setSourceClass(deduceMainApplicationClass());
return (getSourceClass() != null ? ClassUtils.getShortName(getSourceClass()) : "application");
}
protected String getcurrentThreadName(String ThreadName, String applicationName) {
StringBuffer sb = new StringBuffer();
sb.append(ThreadName);
sb.append("-");
sb.append(applicationName);
return sb.toString();
}
}
在spring.factories中配置
org.springframework.context.ApplicationListener=com.xxx.xxx.dubbo.listener.DubboHolderListener
这样每次引入dubbo-starter,就可以springboot启动dubbo服务了! ∶)
官方是不是说下一个版本会有 spring-boot-starter dubbo 集成吗 github 上有阿里写的 spring-boot-starter-dubbo 例子 而且是可用的 就是有bug
目前网上开源很多dubbo的starter或者其他的方案,总是有各种各样的问题,例如: 1.使用springboot插件不能用插件去启动,只能run application,否则会报消费者找不到服务提供者空指针异常(使用的reference注解会报空指针) 2.服务提供者下线,消费者获取不到,导致消费者引用的reference注解报空指针异常