admin 發表於 2022-6-15 15:37:31

業務中台設計实例 - CSDN

/**
* 扩大点扫描、注册
*/
public class ExtPointBeanPostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* 辨認扩大点实例, 并完成扩大点注册
* 1.扩大点必需实現IExtensionPoint接口
* 2.强迫请求扩大点接口名必需以ExtPt末端
*/
@Override
public Object台中機車借款, postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof IExtensionPoint) {
IExtensionPoint extPoint = (IExtensionPoint) bean;

ExtensionCoordinate coordinate = parseExtensionCoordinate(bean.getClass());
IExtensionPoint oldValue = ExtensionManager.getInstance()
.registerExtPoint(coordinate, extPoint);
if (Objects.nonNull(oldValue)) {
throw new MidFrameworkException("Duplicate registration for :" + coordinate);
}
}
return bean;
}
private ExtensionCoordinate parseExtensionCoordinate(Class<?> targetBean) {
// 扩大点接口
Optional<Class> extPointClass = checkExtensionPoint(targetBean);
if (!extPointClass.isPresent()) {
throw new MidFrameworkException(
String.format("The name of ExtensionPoint for %s must be end with %s", targetBean, IExtensionPoint.EXT_POINT_NAMING));
}
// 解析@Extension注解
AnnotationAttributes attrs = AnnotatedElementUtils.getMergedAnnotationAttributes(targetBean, Extension.class);
String bizCode = attrs.getString("bizCode");
String name = attrs.getString("name");
String description = attrs.getString("description");
return ExtensionCoordinate.builder()
.bizCode(bizCode)
.extensionPoint(extPointClass.get().getName())
.name(name)
.description(description)
.build();
}
private Optional<Class> checkExtensionPoint(Class<?> targetBean) {
Class[] interfaces = targetBean.getInterfaces();
if (interfaces == null || interfaces.length == 0) {
throw new MidFrameworkException("No extension point interface for " + targetBean);
}
// 扩大点接口名必需以ExtPt末端
return Arrays.stream(interfaces)
.filter(ext -> ext.getSimpleName().endsWith(IExtensionPoint.EXT_POINT_NAMING))
.findFirst();
}
}

颠末以上步调,體系已启動完成,而且所有的扩大点也都完成为了注册。剩下的就是怎样去挪用扩大点法子了!因为统一個扩大点的所有实例多是统一個名字,好比都叫
BuyExtPointImpl,明顯不克不及經由過程Spring的依靠注入来挪用。究竟上,扩大点实例的挪用,都是同一走扩大点履行器,其内部封装了扩大点查找逻辑和履行逻辑,代码注释應當写得比力清晰了。

/**
* 扩大点实例履行器: 封装扩大点查找计谋及法子挪用
*/
public class ExtensionExecutor{
private ExtensionExecutor() {
throw new IllegalStateException("No instance");
}
/**
* 有返回值
*
* @param targetClass 扩大点类名
* @param bizId       营業身份
* @param exeFunction 必要挪用的扩大点法子
*/
public static <R, T> R execute(BizId bizId, Class<T> targetClass, Function<T, R> exeFunction) {
T component = findComponent(bizId, targetClass);
return exeFunction.apply(component);
}
/**
* 無返回值
*
* @param targetClass 扩大点类名
* @param bizId       营業身份
* @param exeConsumer 必要挪用的扩大点法子
*/
public static <T> void consume(BizId bizId, Class<T> targetClass, Consumer<T> exeConsumer) {
T component = findComponent(bizId, targetClass);
exeConsumer.accept(component);
}
/**
* 切确查找扩大点: 先看是不是有营業实現的扩大点;若没有,再看是不是有平台默许实現
*/
@SuppressWarnings("unchecked")
private static <T> T findComponent(BizId bizId, Class<T> targetClass) {
ExtensionCoordinate bizCoordinate = ExtensionCoordinate.of(bizId.getBizCode(), targetClass.getName());
IExtensionPoint extension = ExtensionManager.getInstance().findExtPoint(bizCoordinate);
if (Objects.isNull(extension)) {
ExtensionCoordinate systemCoordinate = ExtensionCoordinate.of(IExtensionPoint.SYSTEM_BIZ_CODE,
targetClass.getName());
extension = ExtensionManager.getInstance().findExtPoint(systemCoordinate);
}
if (Objects.isNull(extension)) {
throw new MidFrameworkException("Not found extension: " + bizCoordinate);
}
return (T) extension;
}
}

下面以一個单测为例演示扩大点的履行 ExtensionExecutor.execute()

@Test
public void testTaobaoExt() {
BizId bizId = new BizId("com.taobao");
int promotion = ExtensionExecutor.execute(bizId, PromotionCalcExtPoint.class,
PromotionCalcExtPoint::calcPromotion);
Assert.539版路單,assertEquals(promotion, 80);
}
@Test
public void testTmallExt() {
BizId bizId = new BizId("com.tmall");
int promotion = ExtensionExecutor.exec君綺PTT,ute(隱形矯姿帶,bizId, PromotionCalcExtPoint.class,
PromotionCalcExtPoint::calcPromotion);
Assert.assertEquals(promotion, 90);
}

上面2末節,已把扩大点注册和扩大点履行,触及到的数据模子、運行機制論述清晰了。這里再補一幅圖来個更直观感觉。
頁: [1]
查看完整版本: 業務中台設計实例 - CSDN