/**
* 桥接接口初始化类
*/
public class RemoteServiceCreator {
private static Logger log = LoggerFactory.getLogger(RemoteServiceCreator.class);
@Autowired
private SpringIocUtil springIocUtil;
@Autowired
private BeanDynamicCreator beanDynamicCreator;
@Autowired
private DisconfigHolder disconfigHolder;
//解析结果
private final Map remoteProcessorMap = Maps.newHashMap();
//基础接口全路径
private static final String baseInterfaceName = "com.netease.kaola.pages.bridge.processor.PageBridgeProcessor";
@Value("${dubbo.consumer.group}")
private String remoteDubboGroup;
/**
* 定时任务,手动触发
*/
public void refreshRemoteService() {
log.info("kschedule task refreshRemoteService start");
initRemoteService();
log.info("kschedule task refreshRemoteService end");
}
/**
* 解析配置,注册spring bean 及 dubbo消费者; 作为init-method,服务启动,bean初始化时执行
*/
public void initRemoteService() {
//解析配置信息, 配置第三方服务与区块type映射信息,包括类路径、dubbo group version等
List remoteConfigModels = getRemoteServiceConfig();
if (CollectionUtils.isEmpty(remoteConfigModels)) {
log.info("配置信息为空");
return;
}
long beginTime = System.currentTimeMillis();
log.info("[RemoteServiceCreator] begin init remote service, beginTime :" + beginTime);
for (RemoteConfigModel remoteConfigModel : remoteConfigModels) {
//配置信息基本校验
if (!checkConfig(remoteConfigModel)) {
continue;
}
//兼容本地实现
if (remoteConfigModel.isDefaultFlag()) {
PageBridgeProcessor pageBridgeProcessor = (PageBridgeProcessor) springIocUtil.getBean("commonProcessor");
if (pageBridgeProcessor == null) {
log.error("[RemoteServiceCreator] 默认实现不存在,请检查");
} else {
bindProcess(remoteConfigModel.getRegionType(), pageBridgeProcessor);
}
continue;
}
String targetFullName = remoteConfigModel.getTargetFullName();
if (springIocUtil.containsBean(targetFullName)) {
//已经构建过,直接绑定,兼容不同type,调用同一实现
PageBridgeProcessor pageBridgeProcessor = (PageBridgeProcessor) springIocUtil.getBean(targetFullName);
bindProcess(remoteConfigModel.getRegionType(), pageBridgeProcessor);
continue;
}
try {
if (checkIsExistClass(targetFullName)) {
log.error("[RemoteServiceCreator] initRemoteService error, targetFullName already is class, " +
"targetFullName:" + targetFullName);
}else {
//远程是否接口未引入,基于javassist,动态创建dubbo接口对应的api
parse(baseInterfaceName, targetFullName);
}
if (!checkIsExistClass(targetFullName)) {
log.info("[RemoteServiceCreator] initRemoteService error, targetFullName:" + targetFullName);
continue;
}
DefaultListableBeanFactory factory = beanDynamicCreator.getBeanFactory();
if (factory.containsBean(targetFullName)) {
continue;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(ReferenceBean.class);//设置为ReferenceBean,getBean()时就会走到dubbo服务发现逻辑
beanDefinition.setLazyInit(false);
factory.registerBeanDefinition(targetFullName, beanDefinition);
beanDefinition.getPropertyValues().addPropertyValue("id", targetFullName);
beanDefinition.getPropertyValues().addPropertyValue("interface", targetFullName);
//设置版本
if (StringUtils.isNotBlank(remoteConfigModel.getDubboVersion())) {
beanDefinition.getPropertyValues().addPropertyValue("version", remoteConfigModel.getDubboVersion());
}
//设置分组
if (StringUtils.isNotBlank(remoteConfigModel.getDubboGroup())) {
beanDefinition.getPropertyValues().addPropertyValue("group", remoteConfigModel.getDubboGroup());
} else {
beanDefinition.getPropertyValues().addPropertyValue("group", remoteDubboGroup);
}
//getBean会实例化
PageBridgeProcessor object = (PageBridgeProcessor) factory.getBean(targetFullName);
log.info("[RemoteServiceCreator] init remote service " + targetFullName + " " + object);
if (object != null) {
bindProcess(remoteConfigModel.getRegionType(), object);
}
} catch (Exception t) {
log.info("[RemoteServiceCreator] initRemoteService error, targetFullName:" + targetFullName, t);
}
log.info("[RemoteServiceCreator] end init remote service, cost :" + (System.currentTimeMillis() -
beginTime));
}
}
private List getRemoteServiceConfig() {
List list = Lists.newArrayList();
String json = disconfigHolder.getBridgeRemoteServiceConfig();
if (StringUtils.isBlank(json)) {
return list;
}
try {
list = FastJsonUtil.parseList(json, RemoteConfigModel.class);
} catch (Exception e) {
log.error("[RemoteServiceCreator] 解析配置异常", e);
}
return list;
}
private boolean checkIsExistClass(String targetFullName) {
try {
Class clazz = Class.forName(targetFullName);
return clazz != null;
} catch (Exception e) {
return false;
}
}
//根据区块类型查询实现类
public PageBridgeProcessor getRemoteProcessor(Integer regionType) {
return remoteProcessorMap.get(regionType);
}
public Map getRemoteProcessorMap() {
return remoteProcessorMap;
}
//绑定服务
private void bindProcess(Integer regionType, PageBridgeProcessor processor) {
remoteProcessorMap.put(regionType, processor);
}
/**
* 动态创建接口,远程接口未引入
*
* @param baseFullName 基础接口全路径
* @param targetFullName 目标接口
* @throws Throwable
*/
private void parse(String baseFullName, String targetFullName) throws Exception {
ClassPool pool = ClassGenerator.getClassPool(ClassHelper.getCallerClassLoader(Wrapper.class));
CtClass baseClazz = pool.get(baseFullName);
//动态创建远程接口类,继承桥接基础接口
pool.makeInterface(targetFullName, baseClazz).toClass();
}
//基本校验
private boolean checkConfig(RemoteConfigModel remoteConfigModel) {
if (remoteConfigModel == null) {
return false;
}
if (!remoteConfigModel.isDefaultFlag() && StringUtils.isBlank(remoteConfigModel.getTargetFullName())) {
log.error("[RemoteServiceCreator-checkConfig] 远程实现接口不能为空");
return false;
}
if (!remoteConfigModel.isDefaultFlag() && remoteConfigModel.getTargetFullName().equals(baseInterfaceName)) {
log.error("[RemoteServiceCreator-checkConfig] 远程实现接口不能直接使用基础接口");
return false;
}
return true;
}
接口入参:
public class FrontPageParam extends BaseParam{
private static final long serialVersionUID = 1L;
/**
* 区块类型,用于判断走什么处理逻辑
*/
private int regionType;
/**
* 区块资源id
*/
private Long regionId;
/**
* 动态参数,具体业务自己定义,建议传json格式
*/
private String dynamicParams ;
/**
* 预览标识, true: 预览, false: 非预览; 默认不是预览
*/
private boolean previewFlag = false;
/**
* 请求来源,用于区分来自哪种页面
*/
private Integer requestSource;
/**
* 模块id 预留
*/
private Long moduleId;
/**
* 模块类型,预留
*/
private int moduleType;
/**
* 页面id,预留
*/
private Long pageId;
}
应用效果: