管道流设计模式结合业务

news2024/11/25 19:38:06

文章目录

    • 流程图
    • 代码实现
      • pom
      • context
        • EventContext
        • BizType
        • AbstractEventContext
      • filter
        • EventFilter
        • AbstractEventFilter
        • EventFilterChain
        • FilterChainPipeline
        • DefaultEventFilterChain
      • selector
        • FilterSelector
        • DefaultFilterSelector
    • 调用代码
      • PipelineApplication
      • controller
      • entity
      • service
      • service.business1
      • service.business1.context
      • service.business1.filters
      • service.business1.plugins
      • service.business2
      • service.business2.context
      • service.business2.filters
      • service.business2.plugins
      • service.config
      • service.selector
      • application.yml

流程图

请添加图片描述

代码实现

请添加图片描述

完整代码:https://gitee.com/gitee_pikaqiu/easy-pipeline

pom

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.plugin</groupId>
        <artifactId>spring-plugin-core</artifactId>
        <version>${spring.plugin.core.version}</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool.version}</version>
    </dependency>
</dependencies>

context

EventContext
public interface EventContext {


    /**
     * 是否继续调用链
     */
    boolean continueChain();


    /**
     * 获取当前过滤器选择器
     */
    FilterSelector getFilterSelector();

}
BizType
public interface BizType {


    /**
     * 获取业务类型码值
     */
    Integer getCode();

    /**
     * 业务类型名称
     *
     */
    String getName();

}
AbstractEventContext
public abstract class AbstractEventContext implements EventContext{


    private final BizType businessType;
    private final FilterSelector filterSelector;


    protected AbstractEventContext(BizType businessType, FilterSelector filterSelector) {
        this.businessType = businessType;
        this.filterSelector = filterSelector;
    }


    @Override
    public boolean continueChain() {
        return true;
    }

    @Override
    public FilterSelector getFilterSelector() {
        return filterSelector;
    }

}

filter

EventFilter
public interface EventFilter<T extends EventContext> {

    /**
     * 过滤逻辑封装点
     *
     * @param context 上下文对象
     * @param chain   调用链
     */
    void doFilter(T context, EventFilterChain<T> chain);

}
AbstractEventFilter
public abstract class AbstractEventFilter<T extends EventContext> implements EventFilter<T> {

    @Override
    public void doFilter(T context, EventFilterChain<T> chain) {
        // 执行
        if (context.getFilterSelector().matchFilter(this.getClass().getSimpleName())) {
            handler(context);
        }

        // 是否继续执行调用链
        if (context.continueChain()) {
            chain.nextHandler(context);
        }
    }


    /**
     * 执行器
     *
     * @param context 上下文对象
     */
    protected abstract void handler(T context);

}
EventFilterChain
public interface EventFilterChain<T extends EventContext> {


    /**
     * 执行当前过滤器
     *
     * @param context 上下文对象
     */
    void handler(T context);


    /**
     * 跳过当前过滤器 执行下一个执行过滤器
     *
     * @param context 上下文对象
     */
    void nextHandler(T context);

}
FilterChainPipeline
@Slf4j
@Component
public class FilterChainPipeline<F extends EventFilter>{


    private DefaultEventFilterChain<EventContext> last;


    public FilterChainPipeline<F> append(F filter){
        last = new DefaultEventFilterChain<>(last, filter);
        return this;
    }


    public FilterChainPipeline<F> append(String description, F filter){
        log.debug("过滤器调用链管道开始设置 {} 过滤器",description);
        last = new DefaultEventFilterChain<>(last, filter);
        return this;
    }


    public DefaultEventFilterChain<EventContext> getFilterChain() {
        return this.last;
    }

}
DefaultEventFilterChain
public class DefaultEventFilterChain<T extends EventContext> implements EventFilterChain<T> {

    private final EventFilterChain<T> next;
    private final EventFilter<T> filter;


    public DefaultEventFilterChain(EventFilterChain<T> next, EventFilter<T> filter) {
        this.next = next;
        this.filter = filter;
    }


    @Override
    public void handler(T context) {
        filter.doFilter(context,this);
    }

    @Override
    public void nextHandler(T context) {
        if (next != null) {
            next.handler(context);
        }
    }

}

selector

FilterSelector
public interface FilterSelector {


    /**
     * 匹配过滤器
     *
     * @param currentFilterName 过滤器名称
     * @return true 匹配成功
     */
    boolean matchFilter(String currentFilterName);

    /**
     * 获取当前所有过滤器名称
     *
     * @return 过滤器名称
     */
    List<String> getAllFilterNames();
}
DefaultFilterSelector
public class DefaultFilterSelector implements FilterSelector{

    @Setter
    private  List<String> filterNames = CollUtil.newArrayList();

    @Override
    public boolean matchFilter(String currentFilterName) {
        return filterNames.stream().anyMatch(s -> Objects.equals(s,currentFilterName));
    }


    @Override
    public List<String> getAllFilterNames() {
        return filterNames;
    }

}

调用代码

请添加图片描述

PipelineApplication

@SpringBootApplication
@EnablePluginRegistries(value = {Business1PostPlugin.class, Business2PostPlugin.class})
public class PipelineApplication {
    public static void main(String[] args) {
        SpringApplication.run(PipelineApplication.class, args);
    }
}

controller

@RestController
@RequestMapping("/pipelineTest")
public class PipelineController {

    @Autowired
    private Business1Service business1PipelineTestService;

    @Autowired
    private Business2Service business2PipelineTestService;


    @GetMapping("/business1")
    public void business1(){
        PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();
        pipelineTestRequest.setUuid("business1-1110-1111231afsas-123adss");
        pipelineTestRequest.setBusinessCode("business1");
        pipelineTestRequest.setModel2(new Business1Model2());
        pipelineTestRequest.setModel1(new Business1Model1());
        business1PipelineTestService.doService(pipelineTestRequest);
    }


    @GetMapping("/business2")
    public void business2(){
        PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();
        pipelineTestRequest.setUuid("business2-1110-1111231afsas-123adss");
        pipelineTestRequest.setBusinessCode("business2");
        pipelineTestRequest.setModel3(new Business2Model1());
        pipelineTestRequest.setModel4(new Business2Model2());
        business2PipelineTestService.doService(pipelineTestRequest);
    }

}

entity

@Data
public class PipelineRequestVo {


    private String uuid;

    private String businessCode;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model2 model2;


    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model1 model3;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model2 model4;

}

service

@Getter
@AllArgsConstructor
public enum BusinessTypeEnum implements BizType {

    BUSINESS_1(1,"业务1"),
    BUSINESS_2(2,"业务2"),
    BUSINESS_3(3,"业务3"),
    ;



   private Integer code;
   private String name;

}

service.business1

public interface Business1Service {

    void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business1ServiceImpl implements Business1Service {

    @Qualifier("business1PipelineSelectorFactory")
    @Autowired
    private  PipelineSelectorFactory business1PipelineSelectorFactory;

    @Autowired
    private  FilterChainPipeline<Business1PipelineFilter> filterChainPipeline;

    @Autowired
    private  PluginRegistry<Business1PostPlugin, Business1Model1> business1PostPlugin;



    @Override
    public void doService(PipelineRequestVo pipelineTestRequest) {
        log.info("===============business1开始===============");
        // 处理器参数
        log.info("===============开始获取FilterSelector===============");
        FilterSelector filterSelector = business1PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);
        Business1Context pipelineEventContext = new Business1Context(BusinessTypeEnum.BUSINESS_1, filterSelector);
        log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());
        log.info("===============获取FilterSelector完成===============");

        // 处理
        log.info("===============开始执行过滤器===============");
        pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);
        pipelineEventContext.setModel2(pipelineTestRequest.getModel2());
        pipelineEventContext.setModel1(pipelineTestRequest.getModel1());
        filterChainPipeline.getFilterChain().handler(pipelineEventContext);
        log.info("===============执行过滤器完成===============");

        // 处理后获取值
        log.info("===============开始执行后置处理器===============");
        Business1Model2 model2 = pipelineEventContext.getModel2();
        Business1Model1 model1 = pipelineEventContext.getModel1();
        PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();
        business1PostPlugin.getPluginsFor(model1)
                .forEach(handler -> handler.postProcessing(model1));
        log.info("===============执行后置处理器完成===============");

        log.info("===============business1结束===============");

    }

}

service.business1.context

public class Business1Context extends AbstractEventContext {

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model2 model2;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private PipelineRequestVo pipelineTestRequest;


    public Business1Context(BizType businessType, FilterSelector filterSelector) {
        super(businessType, filterSelector);
    }

    @Override
    public boolean continueChain() {
        return true;
    }

}
@Data
public class Business1Model1 {

    private Integer id;

    private String name1;

    private String name2;

    private String name3;

}
@Data
public class Business1Model2 {

    private Integer id;

    private String name;

    private String desc;

    private String age;

}

service.business1.filters

public interface Business1PipelineFilter extends EventFilter<Business1Context> {

    int order();
}
@Slf4j
@Component
public class Business1Filter1 extends AbstractEventFilter<Business1Context> implements Business1PipelineFilter {

    @Override
    public void handler(Business1Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business1Model1 model1 = context.getModel1();
        model1.setName1("张三");
        model1.setName2("李四");
        model1.setName3("王五");
        model1.setId(1);

        Business1Model2 model2 = context.getModel2();
        model2.setId(2);
        model2.setDesc("");
        model2.setAge("18");
        model2.setName("小白");

        log.info("Filter1执行完毕...");

        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(model2);
    }

    @Override
    public int order() {
        return 1;
    }
}
@Slf4j
@Component
public class Business1Filter2 extends AbstractEventFilter<Business1Context>  implements Business1PipelineFilter {

    @Override
    public void handler(Business1Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business1Model1 model1 = context.getModel1();
        model1.setName1(model1.getName1() + "-------------");
        model1.setName2(model1.getName2() + "-------------");
        model1.setName3(model1.getName3() + "-------------");
        model1.setId(100);

        log.info("Filter2执行完毕...");
        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(context.getModel2());
    }

    @Override
    public int order() {
        return 2;
    }
}

service.business1.plugins

public interface Business1PostPlugin extends Plugin<Business1Model1> {


    /**
     * 后置处理
     *
     * @param model 处理参数
     */
    void postProcessing(Business1Model1 model);

}
@Slf4j
@Component
public class Business1ServicePluginImpl implements Business1PostPlugin {


    @Override
    public boolean supports(Business1Model1 pipelineEventContext) {
        return true;
    }


    @Override
    public void postProcessing(Business1Model1 model) {
        log.info("===>{}",model.getId());
    }

}
@Slf4j
@Component
public class Business1ServicePluginImpl2 implements Business1PostPlugin {

    @Override
    public boolean supports(Business1Model1 model) {
        return true;
    }


    @Override
    public void postProcessing(Business1Model1 model) {
        log.info("===>{}",model.getId());
    }

}

service.business2

public interface Business2Service {

    void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business2ServiceImpl implements Business2Service {

    @Qualifier("business2PipelineSelectorFactory")
    @Autowired
    private PipelineSelectorFactory business2PipelineSelectorFactory;

    @Autowired
    private FilterChainPipeline<Business2PipelineFilter> filterChainPipeline;

    @Autowired
    private PluginRegistry<Business2PostPlugin, Business2Model1> business2PostPlugin;



    @Override
    public void doService(PipelineRequestVo pipelineTestRequest) {
        log.info("===============business2开始===============");
        // 处理器参数
        log.info("===============开始获取FilterSelector===============");
        FilterSelector filterSelector = business2PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);
        Business2Context pipelineEventContext = new Business2Context(BusinessTypeEnum.BUSINESS_2, filterSelector);
        log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());
        log.info("===============获取FilterSelector完成===============");

        // 处理
        log.info("===============开始执行过滤器===============");
        pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);
        pipelineEventContext.setModel2(pipelineTestRequest.getModel4());
        pipelineEventContext.setModel1(pipelineTestRequest.getModel3());
        filterChainPipeline.getFilterChain().handler(pipelineEventContext);
        log.info("===============执行过滤器完成===============");

        // 处理后获取值
        log.info("===============开始执行后置处理器===============");
        Business2Model2 model2 = pipelineEventContext.getModel2();
        Business2Model1 model1 = pipelineEventContext.getModel1();
        PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();
        business2PostPlugin.getPluginsFor(model1)
                .forEach(handler -> handler.postProcessing(model1));
        log.info("===============执行后置处理器完成===============");
        log.info("===============business2结束===============");
    }

}

service.business2.context

public class Business2Context extends AbstractEventContext {

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model2 model2;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private PipelineRequestVo pipelineTestRequest;


    public Business2Context(BizType businessType, FilterSelector filterSelector) {
        super(businessType, filterSelector);
    }

    @Override
    public boolean continueChain() {
        return true;
    }

}
@Data
public class Business2Model1 {

    private Integer id;

    private String name1;

    private String name2;

    private String name3;

}
@Data
public class Business2Model2 {

    private Integer id;

    private String name;

    private String desc;

    private String age;

}

service.business2.filters

public interface Business2PipelineFilter extends EventFilter<Business2Context> {

     int order();
}
@Slf4j
@Component
public class Business2Filter1 extends AbstractEventFilter<Business2Context> implements Business2PipelineFilter {

    @Override
    public void handler(Business2Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business2Model1 model1 = context.getModel1();
        model1.setName1("张三");
        model1.setName2("李四");
        model1.setName3("王五");
        model1.setId(1);

        Business2Model2 model2 = context.getModel2();
        model2.setId(2);
        model2.setDesc("");
        model2.setAge("18");
        model2.setName("小白");

        log.info("Filter1执行完毕...");

        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(model2);
    }

    @Override
    public int order() {
        return 1;
    }
}
@Slf4j
@Component
public class Business2Filter2 extends AbstractEventFilter<Business2Context>  implements Business2PipelineFilter {

    @Override
    public void handler(Business2Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business2Model1 model1 = context.getModel1();
        model1.setName1(model1.getName1() + "-------------");
        model1.setName2(model1.getName2() + "-------------");
        model1.setName3(model1.getName3() + "-------------");
        model1.setId(100);

        log.info("Filter2执行完毕...");
        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(context.getModel2());
    }

    @Override
    public int order() {
        return 2;
    }
}

service.business2.plugins

public interface Business2PostPlugin extends Plugin<Business2Model1> {


    /**
     * 后置处理
     *
     * @param model 处理参数
     */
    void postProcessing(Business2Model1 model);

}
@Slf4j
@Component
public class Business2ServicePluginImpl implements Business2PostPlugin {


    @Override
    public boolean supports(Business2Model1 pipelineEventContext) {
        return true;
    }


    @Override
    public void postProcessing(Business2Model1 model) {
        log.info("===>{}",model.getId());
    }

}
@Slf4j
@Component
public class Business2ServicePluginImpl2 implements Business2PostPlugin {


    @Override
    public boolean supports(Business2Model1 model) {
        return true;
    }


    @Override
    public void postProcessing(Business2Model1 model) {
        log.info("===>{}",model.getId());
    }

}

service.config

@ConfigurationProperties(prefix = "test")
@Component
@Data
public class FilterConfigProperties {

    private Map<String, List<String>> configs;


    public Map<String, List<String>> getConfigs() {
        if (configs == null) {
            configs = MapUtil.newHashMap(16);
        }
        return configs;
    }

}
@Component
@RequiredArgsConstructor
public class PipelineFilterConfig {

    private final List<Business1PipelineFilter> business1PipelineFilter;
    private final FilterChainPipeline<Business1PipelineFilter> business1FilterChainPipeline;

    private final List<Business2PipelineFilter> business2PipelineFilter;
    private final FilterChainPipeline<Business2PipelineFilter> business2FilterChainPipeline;

    private final FilterConfigProperties filterConfigProperties;


    @Bean
    public FilterChainPipeline<Business1PipelineFilter> business1ChargePipeline() {
        Map<String, List<String>> configs = filterConfigProperties.getConfigs();
        if (business1PipelineFilter.isEmpty() || configs.isEmpty()){
            return business1FilterChainPipeline;
        }

        Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();
        long distinctCount = filtersName.stream().distinct().count();
        if (distinctCount > business1PipelineFilter.size()) {
            throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");
        }

        business1PipelineFilter
                .stream()
                .sorted(Comparator.comparing(Business1PipelineFilter::order))
                .forEach(business1FilterChainPipeline::append)
        ;
        return business1FilterChainPipeline;
    }


    @Bean
    public FilterChainPipeline<Business2PipelineFilter> business2ChargePipeline() {
        Map<String, List<String>> configs = filterConfigProperties.getConfigs();
        if (business2PipelineFilter.isEmpty() || configs.isEmpty()){
            return business2FilterChainPipeline;
        }

        Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();
        long distinctCount = filtersName.stream().distinct().count();
        if (distinctCount > business2PipelineFilter.size()) {
            throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");
        }

        business2PipelineFilter
                .stream()
                .sorted(Comparator.comparing(Business2PipelineFilter::order))
                .forEach(business2FilterChainPipeline::append)
        ;
        return business2FilterChainPipeline;
    }

}

service.selector

public interface PipelineSelectorFactory {
    FilterSelector  getFilterSelector(PipelineRequestVo request);
}
@Component("business1PipelineSelectorFactory")
public class Business1PipelineSelectorFactory implements PipelineSelectorFactory {

    @Autowired
    private FilterConfigProperties filterConfigProperties;

    @Override
    public FilterSelector getFilterSelector(PipelineRequestVo request) {
        String businessCode = request.getBusinessCode();
        DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();
        if (businessCode.equals("business1")){
            defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));
        }
        return defaultFilterSelector;
    }
}
@Component("business2PipelineSelectorFactory")
public class Business2PipelineSelectorFactory implements PipelineSelectorFactory {

    @Autowired
    private FilterConfigProperties filterConfigProperties;

    @Override
    public FilterSelector getFilterSelector(PipelineRequestVo request) {
        String businessCode = request.getBusinessCode();
        DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();
        if (businessCode.equals("business2")){
            defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));
        }
        return defaultFilterSelector;
    }

}

application.yml

server:
  port: 8080

test:
  configs:
    business1:
      - Business1Filter1
      - Business1Filter2
    business2:
      - Business2Filter1
      - Business2Filter2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1607133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线上线下交友社区系统 可打包小程序 支持二开 源码交付!

社交网络的普及&#xff0c;人们交友的方式发生了巨大的变化。过去&#xff0c;我们主要通过线下的方式来结识新朋友&#xff0c;比如在学校、工作场所、社交活动或者兴趣小组中。然而&#xff0c;随着移动端软件的发展&#xff0c;线上交友也逐渐变得流行。 方便性&#xff1a…

FreeRTOS学习 -- 中断配置

一、什么是中断 中断时微控制器一个很常见的特性&#xff0c;中断是由硬件产生&#xff0c;当中断产生以后CPU就会中断当前的流程而去处理中断服务&#xff0c;Cortex-M内核的MCU提供了一个用于中断管理的嵌套向量中断控制器&#xff08;NVIC&#xff09;。 二、中断优先级分…

波士顿动力抛弃液压机器人Atlas,推出全新电动化机器人,动作超灵活

本周&#xff0c;机器人科技巨头波士顿动力宣布液压Atlas退役&#xff0c;并推出了下一代产品——专为实际应用而设计的全电动Atlas机器人&#xff0c;这也意味着人形机器人迈出了商业化的第一步。 Atlas——人形机器人鼻祖 Atlas&#xff08;阿特拉斯&#xff09;这个名字最…

为什么有的云渲染注册条件哪么多?有没有注册条件少的?

随着云渲染技术的普及&#xff0c;越来越多的设计师、艺术家和企业开始依赖这一强大的工具来加速创作过程。但是在我们注册账号的时候你会发现不同平台间的注册条件不同&#xff0c;一些平台在用户注册过程中设置了一系列繁琐的验证环节&#xff0c;让我们填那种无意义的数字或…

java体育馆使用预约平台的设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的体育馆使用预约平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 体育馆使用预约平台的…

ruoyi-nbcio-plus基于vue3的多租户机制

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

饮料市场迎来“营养革命”?2024年饮料行业销售数据分析已出炉

随着健康意识的日益增强&#xff0c;消费者对于饮料的需求已经不再是单纯追求口感和美味&#xff0c;而是更加关注产品的营养价值和健康属性。在这种背景下&#xff0c;上海市卫生健康委近期启动了“首批营养健康指导试点项目”&#xff0c;其中饮料“营养选择”分级标识试点的…

DFS专题:力扣岛屿问题(持续更新)

DFS专题&#xff1a;力扣岛屿问题 开篇 每次做到DFS相关的题目都是直接跳过。蓝桥杯过后痛定思痛&#xff0c;好好学习一下DFS和BFS。先从DFS开始吧。 参考题解&#xff1a;nettee&#xff1a;岛屿类问题的通用解法、DFS 遍历框架 题目链接&#xff1a; 200.岛屿数量    …

机器学习波士顿房价

流程 数据获取导入需要的包引入文件,查看内容划分训练集和测试集调用模型查看准确率 数据获取 链接&#xff1a;https://pan.baidu.com/s/1deECYRPQFx8h28BvoZcbWw?pwdft5a 提取码&#xff1a;ft5a --来自百度网盘超级会员V1的分享导入需要的包 import pandas as pd imp…

FreeRTOS之动态创建任务与删除任务

1.本文是利用FreeRTOS来动态创建任务和删除任务。主要是使用FreeRTOS的两个API函数&#xff1a;xTaskCreate()和vTaskDelete()。 任务1和任务2是让LED0、LED1闪烁。任务3是当按键按下时删除任务1。 使用动态创建任务时&#xff0c;需要动态的堆中申请任务所需的内存空间&…

Eagle for Mac v1.9.13注册版:强大的图片管理工具

Eagle for Mac是一款专为Mac用户设计的图片管理工具&#xff0c;旨在帮助用户更高效、有序地管理和查找图片资源。 Eagle for Mac v1.9.13注册版下载 Eagle支持多种图片格式&#xff0c;包括JPG、PNG、GIF、SVG、PSD、AI等&#xff0c;无论是矢量图还是位图&#xff0c;都能以清…

软考 系统架构设计师系列知识点之大数据设计理论与实践(11)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之大数据设计理论与实践&#xff08;10&#xff09; 所属章节&#xff1a; 第19章. 大数据架构设计理论与实践 第3节 Lambda架构 19.3.6 Lambda与其它架构模式对比 Lambda架构的诞生离不开很多现有设计思想和架构的铺垫…

ctfhub-ssrf(2)

1.URL Bypass 题目提示:请求的URL中必须包含http://notfound.ctfhub.com&#xff0c;来尝试利用URL的一些特殊地方绕过这个限制吧 打开环境发现URL中必须包含http://notfound.ctfhub.com&#xff0c;先按照之前的经验查看127.0.0.1/flag.php,发现没什么反应&#xff0c;按照题…

excel表格如何筛选重复的内容并单独显示

在处理Excel数据时&#xff0c;遇到大量数据时需要筛选数据中的重复值并单独显示出来&#xff0c;那么此时该如何处理呢&#xff1f;事实上在Excel表格中筛选出重复的内容并单独显示的方法有很多种&#xff0c;以下是其中常用的3种&#xff1a; 方法一&#xff1a;使用条件格式…

每日OJ题_多源BFS①_力扣542. 01 矩阵(多源BFS解决最短路原理)

目录 多源BFS解决最短路算法原理 力扣542. 01 矩阵 解析代码 多源BFS解决最短路算法原理 什么是单源最短路 / 多源最短路&#xff1f; 之前的BFS解决最短路都是解决的单源最短路。 画图来说&#xff0c;单源最短路问题即为&#xff1a; 而对于多源最短路问题: 如何解决此…

全球排名前十的搜索引擎,你猜百度排名在第几位?bing稳居二位!

通常情况下&#xff0c;营销人员在争夺其在线业务的流量时会非常关注Google&#xff0c;无论是通过他们的网站&#xff0c;博客文章还是其他形式的内容。考虑到谷歌无疑是最受欢迎的搜索引擎&#xff0c;拥有超过85%的搜索市场份额&#xff0c;这是有道理的。 但这种受欢迎程度…

STM32使用HAL库解码433遥控芯片EV1527

1、首先了解一下433遥控芯片ev1527的基本资料&#xff1a; 这是他编码的关键信息&#xff1a; 也就是说&#xff0c;一帧数据是&#xff1a;一个同步码20位内码4位按键码。 内码20位2^201048576个地址。 发送就是一帧数据接一帧数据不间断发送。 2、解码思路 从上面的帧结构…

node-mysql数据库的下载与安装

01 mysql数据库的安装 网址&#xff1a;mysql.com/downloads/ 打开之后往下翻 点击 MySQL Community (GPL) Downloads 》 点击 MySRL Community Server 再点击 No thanks,just stant my download. 02 安装mysql 03 安装完成之后检查mysql服务是否开启 services.msc 04 启动…

vue3【详解】 vue3 比 vue2 快的原因

使用 Proxy 实现响应式 vue3使用的 Proxy 在处理属性的读取和写入时&#xff0c;比vue2使用的defineProperty 有更好的性能&#xff08;速度加倍的同时&#xff0c;内存还能减半&#xff01;&#xff09; 更新类型标记 Patch Flag 在编译模板时&#xff08;将vue语法转换为js描…

Seal^_^【送书活动第一期】——《Vue.js+Node.js全栈开发实战(第2版)》

Seal^_^【送书活动第一期】——《Vue.jsNode.js全栈开发实战&#xff08;第2版&#xff09;》 一、参与方式二、本期推荐图书2.1 前 言2.2 作者简介2.3 图书简介2.4 本书特色2.5 编辑推荐2.6 书籍目录 三、正版购买 一、参与方式 1、关注博主的账号。 2、点赞、收藏、评论博主的…