JAVA设计模式:注解+模板+接口

1.基础组件

1.1注解类控制代码执行启动、停止、顺序

java 复制代码
/**
 * @author : test
 * @description : 数据同步注解
 * @date : 2025/4/18
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SyncMeta {
    
    /**
     * 执行服务名称
     * @return
     */
    String name() default "";
    
    /**
     * 是否启用
     *
     * @return
     */
    boolean isEnable() default false;
    
    /**
     * 顺序
     * @return
     */
    int order() default 0;
    
}

1.2数据获取基类

1.2.1数据获取基类接口(interface)

java 复制代码
/**
 * @author : test
 * @description :
 * @date : 2025/4/18
 */
public interface BaseDataAcquisition {  
    /**
     * 获取第三方数据
     */
    void acquire();  
}

1.2.2数据获取基类抽象类(abstract)实现接口

java 复制代码
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
 * @author : test
 * @description :
 * @date : 2025/4/18
 */
@Slf4j
public class BaseDataAcquisitionImpl<M extends BaseMapper<T>, T> implements BaseDataAcquisition {

    @Autowired
    protected M baseMapper;
    
    @Autowired
    protected SyncUrlProperties syncUrlProperties;
    
    @Resource
    protected ThirdDatabaseMapper thirdDatabaseMapper;

    @Override
    public void acquire() {
        acquireData(DataSouceEnum.DATASOURCE);
    }
    /**
     * 数据来源方式
     */
    protected void acquireData(DataSouceEnum dataSouceEnum) {
        List<T> allData = new ArrayList<>();
        switch (dataSouceEnum) {
            case DATASOURCE:
                allData = getThirdDataFromDB();
                break;
            case INTERFACE:
                allData = getDataFromUrl();
                break;
            default:
                break;
        }

        if (CollUtil.isEmpty(allData)) {
            log.error("采集数据为空,请确认数据采集方式");
            return;
        }
        //数据抽取,新增
        addExtraData(allData);
        //数据处理
        dealData(allData);
        //集合切分,数据批处理
        List<List<T>> parts = Lists.partition(allData, 1000);
        parts.stream().forEach(list -> saveOrUpdate(list));
       //数据抽取处理
        extraDeal();
    }

    /**
     * 用来重写
     *
     * @return
     */
    protected List<T> getThirdDataFromDB() {
        return null;
    }

    /**
     * 用来重写
     *
     * @return
     */
    protected List<T> getDataFromUrl() {
        return covert(null);
    }


    /**
     * 用来重写
     * 数据保存和更新
     * @param part
     */
    protected void saveOrUpdate(List<T> part) {

    }
    /**
     * 用来重写
     * 数据转换
     * @param body
     */
    protected List<T> covert(String body) {
        List<T> allData = new ArrayList<>();
        return allData;
    }

    /**
     * 用来重写
     * 新增抽取数据
     * @param allData
     */
    protected void addExtraData(List<T> allData) {
    }
    /**
     * 用来重写
     * 数据处理
     * @param allData
     */
    protected void dealData(List<T> allData) {
    }
    /**
     * 用来重写
     * 抽取数据处理
     * @param allData
     */
    protected void extraDeal() {
    }


}

2.数据抽取实现

2.1人员数据抽取示例

java 复制代码
@Service
@SyncMeta(name = Constants.PERSON_SERVICE, isEnable = false, order = 2)
@Slf4j
public class PersonDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdPersonMapper, ThirdPerson>{
    /**
     * 三方数据获取
     */
    @Override
    protected List getThirdDataFromDB() {
        return thirdDatabaseMapper.getAllThirdPerson();
    }
    
    @Override
    protected List getDataFromUrl() {
        String url = syncUrlProperties.getPersonUrl();
        String body = HttpRequest.get(url)
                .timeout(3000)
                //.body(new JSONObject())  get请求发送body会报错,post请求需放开注释
                .execute().body();
        return covert(body);
    }
    
    @Override
    protected void saveOrUpdate(List part) {
        this.baseMapper.batchSaveOrUpdate(part);
    }
    
    @Override
    protected List covert(String body) {
        List<ThirdPerson> thirdPeople = new ArrayList<>();
        //todo 转换请求结果
        return thirdPeople;
    }
}

2.2组织数据抽取示例

java 复制代码
/**
 * @author : test
 * @description :
 * @date : 2025/4/18
 */
@Service
@SyncMeta(name = Constants.ORG_SERVICE, isEnable = false, order = 1)
@Slf4j
public class OrgDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdOrgMapper, ThirdOrg> {
    
    
    @Autowired
    private ThirdRedisOrgCache thirdRedisOrgCache;
    /**
     * 数据库方式获取数据
     */
    @Override
    protected List<ThirdOrg> getThirdDataFromDB() {
        return thirdDatabaseMapper.getAllThirdOrg();
    }
    /**
     * url方式获取数据
     */
    @Override
    protected List<ThirdOrg> getDataFromUrl() {
        String url = syncUrlProperties.getOrgUrl();
        String body = HttpRequest.get(url)
                .timeout(5000)
                //.body(new JSONObject())  get请求发送body会报错,post请求需放开注释
                .execute().body();
        return covert(body);
    }
    /**
     * 数据更新或保存
     */
    @Override
    protected void saveOrUpdate(List<ThirdOrg> part) {
        this.baseMapper.batchSaveOrUpdate(part);
    }
    /**
     * 数据转换
     */
    @Override
    protected List<ThirdOrg> covert(String body) {
        List<ThirdOrg> thirdOrgs = new ArrayList<>();
        //todo 转换请求结果
        return thirdOrgs;
    }
   /**
     * 数据新增
     */
    @Override
    protected void addExtraData(List<ThirdOrg> allData) {
        ThirdOrg thirdOrg = new ThirdOrg();
        thirdOrg.setName(Constants.NO_ORG_NAME_NAME);
        thirdOrg.setThirdCode(Constants.NO_ORG_NAME_CODE);
        thirdOrg.setType(0);
        allData.add(thirdOrg);
    }
   /**
     * 数据处理
     */
    @Override
    protected void extraDeal() {
        thirdRedisOrgCache.initData();
    }
}

2.3 mybatis 数据批量新增更新操作

xml 复制代码
<insert id="batchSaveOrUpdate">
        insert into third_person(
            NAME, CODE, SEX, PHONE, CARD_NUMBER, ID_CARD, EMAIL, ENTRY_DATE, CAR_NUMBER, THIRD_ORG_CODE, THIRD_DORM_CODE, TYPE
        )
        values
        <foreach collection="pojoList" item="item" index="index" separator=",">
            (#{item.name},#{item.code},#{item.sex},#{item.phone},#{item.cardNumber},
            #{item.idCard},#{item.email},#{item.entryDate},#{item.carNumber},
            #{item.thirdOrgCode},#{item.thirdDormCode},#{item.type})
        </foreach>
        ON DUPLICATE KEY UPDATE
        NAME = values(NAME),
        SEX = values(SEX),
        PHONE = values(PHONE),
        CARD_NUMBER = values(CARD_NUMBER),
        EMAIL = values(EMAIL),
        ID_CARD = values(ID_CARD),
        ENTRY_DATE = values(ENTRY_DATE),
        THIRD_ORG_CODE = values(THIRD_ORG_CODE),
        THIRD_DORM_CODE = values(THIRD_DORM_CODE),
        TYPE = values(TYPE),
        UPDATE_TIME = now()
    </insert>

3.数据抽取触发

java 复制代码
/**
 *
 * @author : test
 * @description :
 * @date : 2025/4/18
 */
@Service
public class DataAcquisitionStrategy {
    
    
    public void process(List<String> serviceNames) {
        Map<String, BaseDataAcquisition> allServiceMap = AppContextHelper.getContext().getBeansOfType(BaseDataAcquisition.class);
        List<BaseDataAcquisition> allAcquisitionService = allServiceMap.values().stream().collect(Collectors.toList());
        
        List<BaseDataAcquisition> processServices = allAcquisitionService.stream().filter(service -> {
            SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);
            if (CollUtil.isNotEmpty(serviceNames)) {
                return syncMeta != null && syncMeta.isEnable() && serviceNames.contains(syncMeta.name());
            } else {
                return syncMeta != null && syncMeta.isEnable();
            }
        }).collect(Collectors.toList());
    
        TreeMap<Integer, BaseDataAcquisition> sortedMap = new TreeMap<>();
        processServices.forEach(service->{
            SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);
            sortedMap.put(syncMeta.order(), service);
        });
        sortedMap.values().forEach(service-> service.acquire());
    }
    
  

}
相关推荐
Mcworld85720 分钟前
整数分解JAVA
java·开发语言
小南家的青蛙1 小时前
LeetCode面试题 01.09 字符串轮转
java·leetcode
秋野酱1 小时前
基于javaweb的SpringBoot爱游旅行平台设计和实现(源码+文档+部署讲解)
java·spring boot·后端
饕餮争锋1 小时前
org.slf4j.MDC介绍-笔记
java·开发语言·笔记
shane-u1 小时前
Maven私服搭建与登录全攻略
java·maven
半部论语1 小时前
jdk多版本切换,通过 maven 指定编译jdk版本不生效,解决思路
java·开发语言·maven·intellij-idea
有梦想的攻城狮1 小时前
spring中的@Async注解详解
java·后端·spring·异步·async注解
Python ml1 小时前
Tomcat与纯 Java Socket 实现远程通信的区别
java·开发语言·tomcat
qq_12498707531 小时前
原生小程序+springboot+vue医院医患纠纷管理系统的设计与开发(程序+论文+讲解+安装+售后)
java·数据库·spring boot·后端·小程序·毕业设计
几道之旅2 小时前
分别在windows和linux上使用curl,有啥区别?
linux·运维·windows