dubbo每次从tomcat中undeploy似乎端口都还占用着,网上查了下,说dubbo的关闭是绑定tomcat的关闭事件,然而在项目开发时并不可能每次都关闭tomcat,可能仅仅只需要更新一下提供者就可以了
如有其它解决方案的感谢留言,如今方案纯属下策,由于初次接触dubbo,也没有太熟练.所以就只有先这么玩了..
那么如何避免dubbo的端口配置呢,这个网上有说,不过网上没有提到一些要点,避免其他人跟我一样纠结的调了半天源码才懵懵懂懂的找到原因,将其中的一些细节补充一下
首先是dubbo的配置文件
此处主要是配置dynamicDubboPortReaderDao的这个Bean,class指向你的自定义实现类
PS:
PS:此处有个细节,让我折腾了半天,注意spring配置文件处一定不能写class:applicationContext-*.xml,一定不要让spring走扫描配置文件,否则spring配置文件加载顺序出错,会导致spring在没有初始化dubbo配置文件时初始化service,那么这时候service在初始化,而service暴露给了dubbo,那么dubbo会在此时强制初始化一次,就会先开始dubbo的初始化配置了,而上面配置的bean并没有被用到,所以被延迟实例化了.导致前几个服务会注册到20880端口上
顺便提一下spring配置文件加载顺序:
1.a)如果配置的是*.xml,则扫到一个文件初始化一个文件,此时并没有实例化,只是记录
b)如果配置的是a.xml,b.xml,c.xml的具体文件,则spring按照指定顺序开始扫描
2.spring此时开始实例化扫描到的第一个配置文件从上至下,如果遇到引用的/autoWired等需要注入的对象时,spring将会从实例缓存中寻找该对象,如果有则注入,如果无则实例化该对象后注入,以此类推,完成整个bean的所有注入.
故而产生了上方所述情况,service先加载了,强制实例化了dubbo,而dubbo中配置的bean并没有被引用,所以bean还没有实例化,那么修改端口的操作也就延迟执行了.SO....you know...
package com.cykj.base.service.dubbo;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.PostConstruct;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.config.ProtocolConfig;
/**
* 在dubbo加载配置文件时,会实例化该类,执行init-method配置的init方法
* 此时通过spring获取所有ProtocolConfig的实体(实际上好像就一个),并将其端口设为随机一个未被使用的端口
* 源码中随机端口通过new Socket实现,而后将Socket关闭,更多细节不再说
* @author LeiYong
*/
@Component
public class DynamicDubboPortReaderImpl implements ApplicationContextAware {
@Autowired
private ApplicationContext applicationContext;
private int port = 20880;
@PostConstruct
public void init() {
Map beansOfType = applicationContext.getBeansOfType(ProtocolConfig.class);
for (Entry item : beansOfType.entrySet()) {
port = NetUtils.getAvailablePort();
System.out.println("##################use sure###########################"+port);
item.getValue().setPort(port);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
}