SpringBoot配置类

在Spring Boot中,配置类是一种特殊的类,用于定义和配置Spring应用程序的各种组件、服务和属性。这些配置类通常使用Java注解来声明,并且可以通过Spring的依赖注入机制来管理和使用。

Spring 容器初始化时会加载被@Component、@Service、@Repository、@Controller等注解标识的类,除了注解标识的类,Spring容器还会加载配置类中定义的Bean。配置类通常使用@Configuration注解标识,它们中定义的方法会被Spring容器识别为Bean的创建方法。

本篇主要讲 Springboot 配置类一些常见的用法,按照 SpringBoot 加载顺序配置监听器,过滤器,拦截器,定时器以及读取自定义配置文件。

定义配置类

package com.shore.confittestdemo.config;

import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

}

监听器

`ServletContextListener接口

主要用于监听ServletContext对象的创建和销毁事件。它关注的是Web应用的启动和关闭,以及ServletContext对象的状态变化。

创建一个监听器类,实现ServletContextListener接口

package com.shore.configdemo.config.listener;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;

@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        sce.getServletContext().setAttribute("myApp", "config-demo");
        System.out.println("MyServletContextListener:监听器启动");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println(sce.getServletContext().getAttribute("myApp"));
        System.out.println("MyServletContextListener:监听器销毁");
    }
}

注解 @WebListener 标记为一个监听器类(没啥用)

@Bean
    public ServletContextListener servletContextListener() {
        return new MyServletContextListener();
    }

系统启动时上下文添加 app 信息,系统退出时,获取上下文的 app 信息

ApplicationListener‌ 接口

主要用于监听Spring应用生命周期中的事件,如应用启动、上下文刷新、自定义事件等。它关注的是Spring容器内部的事件。

监听上下文刷新事件

创建一个监听器类,实现 ApplicationListener 接口,指定要监听的事件类型,ContextRefreshedEvent 或者 ContextClosedEvent 或者其他自定义类型的事件,重写 onApplicationEvent 方法,编写监听到事件后需要执行的逻辑。

package com.shore.configdemo.config.listener;

import jakarta.servlet.annotation.WebListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@WebListener
//@Component
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("MyApplicationListener: 监听到上下文刷新" + event);
    }

    @Override
    public boolean supportsAsyncExecution() {
        return ApplicationListener.super.supportsAsyncExecution();
    }
}

配置类中注册 监听器

@Bean
    public MyApplicationListener listener() {
        return new MyApplicationListener();
    }

项目启动创建上下文时被 ServletContextListener 监听到,更新上下文信息,然后被 ApplicationListener 监听器捕获到。

监听上下文刷新和上下文关闭事件

有时候我们希望在一个监听器中监听多个事件,而不是每个事件增加一个监听器类,这时我们可以采用在自定义方法上增加注解 @EventListener,指定要监听的事件类型,一个类中可以有多个注解监听多个事件。

package com.shore.configdemo.config.listener;

import jakarta.servlet.annotation.WebListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;

@WebListener
public class MyMultiEventListener {

    @EventListener
    public void handleContextRefreshEvent(ContextRefreshedEvent event) {
        System.out.println("MyMultiEventListener.handleContextRefreshEvent:监听到上下文刷新");
    }

    @EventListener
    public void handleContextClosedEvent(ContextClosedEvent event) {
        System.out.println("MyMultiEventListener.handleContextClosedEvent:监听到上下文关闭");
    }
}

监听多个自定义事件

实际业务中,我们可能需要监听一些其他的业务,比如类初始化等,可以通过自定义事件来完成。

创建一个类继承 ApplicationEvent 定义一个事件

package com.shore.configdemo.config.event;

import org.springframework.context.ApplicationEvent;

public class MyCustomEvent extends ApplicationEvent {
    private String message;

    public MyCustomEvent(Object source) {
        super(source);
    }

    public MyCustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

定义一个类,调用 ApplicationEventPublisher 接口发布事件

package com.shore.configdemo.config.publisher;

import com.shore.configdemo.config.event.MyCustomEvent;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

@Component
public class MyEventPublisher {
    @Resource
    private ApplicationEventPublisher eventPublisher;

    public void publishEvent() {
        MyCustomEvent myCustomEvent = new MyCustomEvent(this, "Hello, this is custom event");
        eventPublisher.publishEvent(myCustomEvent);
    }
}

在启动类或其他地方调用发布事件方法

package com.shore.configdemo;

import com.shore.configdemo.config.publisher.MyEventPublisher;
import jakarta.annotation.Resource;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigDemoApplication implements CommandLineRunner {
    @Resource
    private MyEventPublisher myEventPublisher;

    public static void main(String[] args) {
        SpringApplication.run(ConfigDemoApplication.class, args);
    }


    @Override
    public void run(String... args) throws Exception {
        myEventPublisher.publishEvent();
    }
}

监听自定义事件

@EventListener
    public void handleMyCustomEvent(MyCustomEvent event) {
        System.out.println("MyMultiEventListener.handleContextClosedEvent:监听到自定义事件:" + event.getMessage());
    }

过滤器

Spring Boot 中的过滤器(Filter)主要用于对请求和响应进行预处理或后处理,常用于处理诸如日志记录、身份验证、头信息处理、请求修改等任务。

新建一个过滤器类,继承 javax.servlet.Filter 接口,也可以继承 OncePerRequestFilter 类,它确保在一次请求中只通过一次filter,无需显式检查是否已过滤。

package com.shore.configdemo.config.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

public class MyCustomFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 过滤器前执行的操作
        System.out.println("MyCustomFilter: Before doFilter");
        System.out.println("Request URI: " + request.getRequestURI());
        System.out.println("Request Method: " + request.getMethod());


        // 继续过滤器链
        filterChain.doFilter(request, response);

        // 过滤器后执行的逻辑
        System.out.println("MyCustomFilter: After doFilter");
        System.out.println("Response Status: " + response.getStatus());
    }
}

在配置类中注册过滤器

@Bean
    public FilterRegistrationBean<MyCustomFilter> myCustomFilter() {
        FilterRegistrationBean<MyCustomFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new MyCustomFilter());

        // 设置特定过滤路径
        filterRegistrationBean.addUrlPatterns("/*");

        // 设置过滤器顺序
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }

通过postman 或者 http 请求在配置类中配置范围的控制器

拦截器

Spring Boot 中的拦截器(Interceptor)主要用于拦截和处理 Spring MVC 框架中的 HTTP 请求和响应。与过滤器(Filter)相比,拦截器更侧重于对 Spring MVC 框架内的请求进行处理,例如,处理控制器方法的前后逻辑。

创建一个拦截器类实现 HandlerInterceptor 接口,重写接口的三个方法 preHandlepostHandleafterCompletion,分别用于在请求处理前、请求处理后(但在视图渲染之前)以及整个请求完成后进行拦截。

package com.shore.configdemo.config.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyCustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在控制器方法执行之前调用
        System.out.println("MyCustomInterceptor: Pre Handle method is Calling");
        // 如果返回 false,将中断请求,不会调用后续的拦截器和控制器方法
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在控制器方法执行之后,视图渲染之前调用
        System.out.println("yCustomInterceptor: Post Handle method is Calling");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求完成之后调用(包括视图渲染和异常处理)
        System.out.println("Request and Response is completed");
    }
}

配置类中注册拦截器,与监听器和过滤器不同,注册拦截器的配置类需要实现 WebMvConfigurer 接口,并重写他的 addInterceptors 方法。

package com.shore.configdemo.config;

import com.shore.configdemo.config.filter.MyCustomFilter;
import com.shore.configdemo.config.interceptor.MyCustomInterceptor;
import com.shore.configdemo.config.listener.MyApplicationListener;
import com.shore.configdemo.config.listener.MyMultiEventListener;
import com.shore.configdemo.config.listener.MyServletContextListener;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContextListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Resource
    private MyCustomInterceptor myCustomInterceptor;

    @Bean
    public FilterRegistrationBean<MyCustomFilter> myCustomFilter() {
        FilterRegistrationBean<MyCustomFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new MyCustomFilter());

        // 设置特定过滤路径
        filterRegistrationBean.addUrlPatterns("/*");

        // 设置过滤器顺序
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myCustomInterceptor)
                .addPathPatterns("/**") // 拦截特定的请求
                .excludePathPatterns("/login"); // 排除特定的请求
    }
}

一旦拦截器被注册到 Spring Boot 应用中,它就会自动对匹配的请求起作用。根据你的配置(如路径模式),每次符合条件的请求都会先经过拦截器,然后再继续处理。

我们在控制器新增两个方法,一个 post 方法用来访问,一个 get 方法用来拦截器重定向,拦截器建议重定向 get 方法

package com.shore.configdemo.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyCustomController {
    @PostMapping("/sayHello")
    public String sayHello() {
        System.out.println("sayHello");
        return "Hello World";
    }

    @GetMapping("/login")
    public String login() {
        System.out.println("login");
        return "login success";
    }
}

我们来分析以下上图的链路,首先我们调用 sayHllo 方法走到过滤器的链路,打印过滤器链之前的逻辑,然后继续后面的过滤器链,接着请求被拦截器拦截到,执行拦截器 preHandler 方法,该方法 重定向到 login 并结束当前链路,不再访问 sayHello,接着 login 又被过滤器捕获到,执行过滤前逻辑,然后被拦截器放行,访问到 login 接口,正常返回又被过滤器捕获到,执行过滤器后置逻辑,至此链路结束。

我们将拦截器中判断 session 返回 false 的逻辑删掉,重新访问 sayHello,执行一次完整的拦截器逻辑.

这里我们可以看到先走到过滤器前置逻辑,接着拦截器 preHandle 方法,然后走到sayHello 接口,然后走到拦截器 postMethod 方法,然后是拦截器 afterCompletion 方法,最后走到过滤器后值逻辑。

定时器

在Spring Boot中,实现定时器功能通常有几种方法,包括使用@Scheduled注解、TaskScheduler接口以及通过@EnableScheduling和配置类来设定定时任务。

@Scheduled注解

@Scheduled注解提供了最简便的方式来声明定时任务。你只需在相应的方法上添加此注解,并指定相应的cron表达式或其他定时规则。

首先,确保你的Spring Boot应用已经启用了定时任务支持,这通常通过在主应用类或配置类上添加@EnableScheduling注解来实现。

package com.shore.configdemo;

import com.shore.configdemo.config.publisher.MyEventPublisher;
import jakarta.annotation.Resource;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class ConfigDemoApplication implements CommandLineRunner {
    @Resource
    private MyEventPublisher myEventPublisher;

    public static void main(String[] args) {
        SpringApplication.run(ConfigDemoApplication.class, args);
    }


    @Override
    public void run(String... args) throws Exception {
        myEventPublisher.publishEvent();
    }
}

创建一个定时任务类,方法使用 @Scheduled 注解标记

package com.shore.configdemo.config.schedule;

import org.springframework.scheduling.annotation.Scheduled;

import java.util.Date;

public class MyCustomScheduleTask {

    @Scheduled(cron = "0 * * * * *")
    public void myScheduleTask() {
        System.out.println("MyCustomScheduleTask: " + new Date());
    }
}

配置类注册定时任务类

@Bean
    public MyCustomScheduleTask myCustomScheduleTask() {
        return new MyCustomScheduleTask();
    }

TaskScheduler接口

如果你需要更细粒度的控制,比如任务池、线程管理等,你可以直接使用TaskScheduler接口。首先,定义一个TaskScheduler的bean

@Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }

然后,你可以注入TaskScheduler并使用它来调度任务

package com.shore.configdemo.service.impl;

import com.shore.configdemo.service.MyService;
import jakarta.annotation.Resource;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class MyServiceImpl implements MyService {
    @Resource
    private TaskScheduler taskScheduler;

    @Override
    public void sayHello(String name) {

    }

    public void scheduleTask() {
        taskScheduler.scheduleWithFixedDelay(() -> {
            System.out.println("执行定时任务: " + new Date());
        }, 5000); // 任务间隔5秒
    }
}

@EnableScheduling和配置类

前面已经提到了@EnableScheduling注解,它用于启用Spring的计划任务调度功能。通常,你只需在主应用类或任何配置类上添加此注解,然后就可以在你的应用中使用@Scheduled注解来声明定时任务了。

除了简单的启用定时任务外,你还可以通过实现SchedulingConfigurer接口来自定义定时任务的配置,比如设置任务执行器(TaskExecutor)或任务调度器(TaskScheduler)的属性。

package com.shore.configdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.util.Date;

@Configuration
@EnableScheduling
public class MyCustomSchedulingTask implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                () -> System.out.println("执行基于触发器的任务: " + new Date()),
                triggerContext -> {
                    // 自定义触发器逻辑,比如根据时间或条件来决定是否执行任务
                    return new CronTrigger("0 * * * * *")
                            .nextExecutionTime(triggerContext)
                            .toInstant();
                }
        );
    }
}

配置文件属性

自定义配置文件 custom-config.yaml

my-app:
  auth-filter:
    secretKey: mySecretKey
    expirationTime: 864000000 # 10 天
    excludes:
      - /shore/demo/user/login
      - /shore/demo/user/register
      - /shore/demo/user/query
  snowflake:
    workerId: 1
    datacenterId: 1

application.yaml 文件配置自定义配置文件的路径

spring:
  config:
    import: classpath:custom-config.yaml

创建配置文件类,指定要读取的标签,定义要读取的属性

package com.shore.my_spring_demo.web.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

@ConfigurationProperties(prefix = "my-app.auth-filter")
@Data
public class CustomAuthFilterConfig {
    private String secretKey;
    private long expirationTime;

    private List<String> excludes;
}

配置类中注册配置文件类

@Bean
    public CustomAuthFilterConfig customAuthFilterConfig() throws NoSuchAlgorithmException {
        return new CustomAuthFilterConfig();
    }

最后就可以在服务中生命使用了

package com.shore.my_spring_demo.service.jwt;

import com.shore.my_spring_demo.common.enums.ErrorEnums;
import com.shore.my_spring_demo.exception.UsersException;
import com.shore.my_spring_demo.web.config.CustomAuthFilterConfig;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.KeyPair;
import java.util.Date;

@Slf4j
@Service
public class JwtServiceImpl implements JwtService {
    @Resource
    private CustomAuthFilterConfig customConfig;

    @Resource
    private KeyPair keyPair;

    @Override
    public String generateTokenAsymmetric(String username) {
        return Jwts.builder()
                .claim("sub", username).claim("role", "admin")
                .expiration(new Date(System.currentTimeMillis() + customConfig.getExpirationTime()))
                .signWith(SignatureAlgorithm.RS256, keyPair.getPrivate())
                .compact();
    }
}

总结

上述所有在配置类中注册的类,大多都可以直接通过注解 @Compent 标记这种简单的方法进行注册,但是如果想要更加精细化的操作,还是需要在配置类中通过 bean 管理注册。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ADS项目笔记 1. 低噪声放大器LNA天线一体化设计

在传统射频结构的设计中&#xff0c;天线模块和有源电路部分相互分离&#xff0c;两者之间通过 50 Ω 传输线级联&#xff0c;这种设计需要在有源电路和天线之间建立无源网络&#xff0c;包括天线模块的输入匹配网络以及有源电路的匹配网络。这些无源网络不仅增加了系统的插入损…

Vue2+ElementUI:用计算属性实现搜索框功能

前言&#xff1a; 本文代码使用vue2element UI。 输入框搜索的功能&#xff0c;可以在前端通过计算属性过滤实现&#xff0c;也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤&#xff0c;后附完整代码&#xff0c;代码中提供的是死数据&#xff0c;可…

【目标检测】用YOLOv8-Segment训练语义分割数据集(保姆级教学)

前言 这篇教程会手把手带你用 YOLOv8-Segment 搭建一个属于自己的分割任务项目。从环境配置到数据集准备&#xff0c;再到模型训练和测试&#xff0c;所有步骤都有详细说明&#xff0c;适合初学者使用。你将学会如何安装必要的软件&#xff0c;标注自己的数据&#xff0c;并使…

Elasticsearch:管理和排除 Elasticsearch 内存故障

作者&#xff1a;来自 Elastic Stef Nestor 随着 Elastic Cloud 提供可观察性、安全性和搜索等解决方案&#xff0c;我们将使用 Elastic Cloud 的用户范围从完整的运营团队扩大到包括数据工程师、安全团队和顾问。作为 Elastic 支持代表&#xff0c;我很乐意与各种各样的用户和…

前深度学习时代-经典的推荐算法

参考自《深度学习推荐系统》—— 王喆&#xff0c;用于学习记录。 1.协同过滤 “协同过滤”就是协同大家的反馈、评价和意见一起对海量的信息进行过滤&#xff0c;从中筛选出目标用户可能感兴趣的信息的推荐过程。 基于用户相似度进行推荐的协同过滤算法 UserCF 用户相似度…

两行命令搭建深度学习环境(Docker/torch2.5.1+cu118/命令行美化+插件),含完整的 Docker 安装步骤

深度学习环境的配置过于繁琐&#xff0c;所以我制作了两个基础的镜像&#xff0c;希望可以帮助大家节省时间&#xff0c;你可以选择其中一种进行安装&#xff0c;版本说明&#xff1a; base 版本基于 pytorch/pytorch:2.5.1-cuda11.8-cudnn9-devel&#xff0c;默认 python 版本…

WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇

WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇 WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇&#xff08;本文&#xff09; WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇 一、前言…

AI在电商平台中的创新应用:提升销售效率与用户体验的数字化转型

1. 引言 AI技术在电商平台的应用已不仅仅停留在基础的数据分析和自动化推荐上。随着人工智能的迅速发展&#xff0c;越来越多的电商平台开始将AI技术深度融合到用户体验、定价策略、供应链优化、客户服务等核心业务中&#xff0c;从而显著提升运营效率和用户满意度。在这篇文章…

Blossom:开源私有部署的markdown笔记软件

在信息化、数字化时代&#xff0c;我们每个人的生活和工作都离不开笔记和知识管理。从简单的待办事项&#xff0c;到复杂的项目计划&#xff0c;再到存储大量个人知识的工具&#xff0c;如何选择一个高效、便捷且符合个人需求的笔记软件&#xff0c;成了许多人的难题。最近在逛…

Linux debian系统安装ClamTk开源图形用户界面(GUI)杀毒软件

一、ClamTk简介 ClamTk 是一个基于 ClamAV 的开源图形用户界面&#xff08;GUI&#xff09;杀毒软件。它使用 GTK2-Perl 脚本构建而成&#xff0c;支持32位与64位操作系统。ClamTk 提供了一个直观的用户界面&#xff0c;使得用户无需深入了解命令行即可完成大部分操作。它具备…

Linux 进程信号的产生

目录 0.前言 1. 通过终端按键产生信号 1.1 CtrlC&#xff1a;发送 SIGINT 信号 1.2 Ctrl\&#xff1a;发送 SIGQUIT 信号 1.3 CtrlZ&#xff1a;发送 SIGTSTP 信号 2.调用系统命令向进程发信号 3.使用函数产生信号 3.1 kill 函数 3.2 raise 函数 3.3 abort 函数 4.由软件条件产…

【大数据学习 | HBASE高级】hive操作hbase

一般在查询hbase的数据的时候我们可以直接使用hbase的命令行或者是api进行查询就行了&#xff0c;但是在日常的计算过程中我们一般都不是为了查询&#xff0c;都是在查询的基础上进行二次计算&#xff0c;所以使用hbase的命令是没有办法进行数据计算的&#xff0c;并且对于hbas…

微信小程序 https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中

授权登录后&#xff0c;拿到用户头像进行加载&#xff0c;但报错提示&#xff1a; https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中 解决方法一&#xff08;未完全解决&#xff0c;临时处理&#xff09;&#xff1a;在微信开发者工具将不校验...勾上就可以访问…

rk3399开发环境使用Android 10初体验蓝牙功能

版本 日期 作者 变更表述 1.0 2024/11/10 于忠军 文档创建 零. 前言 由于Bluedroid的介绍文档有限&#xff0c;以及对Android的一些基本的知识需要了(Android 四大组件/AIDL/Framework/Binder机制/JNI/HIDL等)&#xff0c;加上需要掌握的语言包括Java/C/C等&#xff0…

1. Django中的URL调度器 (项目创建与简单测试)

1. 创建 Django 项目 运行以下命令创建一个名为 blog_project 的 Django 项目&#xff1a; django-admin startproject blog_project2. 创建博客应用 Django 中&#xff0c;项目可以包含多个应用。创建一个名为 blog 的应用&#xff1a; cd blog_project python manage.py …

数据结构(初阶4)---循环队列详解

循环队列 1.循环队列的结构  1).逻辑模式 2.实现接口  1).初始化  2).判断空和满  3).增加  4).删除  5).找头  6).找尾 3.循环队列的特点 1.循环队列的结构 1).逻辑模式 与队列是大同小异的&#xff0c; 其中还是有一个指向队列头的head指针&#xff0c; 也有一个指向尾…

【蓝桥杯算法】Java的基础API

1. BigInteger 的使用 1.1. 判素数 package 模板;import java.math.BigInteger; import java.util.Scanner;public class 判素数 {static Scanner in new Scanner(System.in);public static void main(String[] args) {int q in.nextInt();while (q-- > 0) {BigInteger …

STM32设计井下瓦斯检测联网WIFI加Zigbee多路节点协调器传输

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 本系统基于STM32微控制器和Zigbee无线通信技术&#xff0c;设计了…

320页PDF | 集团IT蓝图总体规划报告-德勤(限免下载)

一、前言 这份报告是集团IT蓝图总体规划报告-德勤。在报告中详细阐述了德勤为某集团制定的全面IT蓝图总体规划&#xff0c;包括了集团信息化目标蓝图、IT应用规划、数据规划、IT集成架构、IT基础设施规划以及IT治理体系规划等关键领域&#xff0c;旨在为集团未来的信息化发展提…

Python毕业设计选题:基于django+vue的二手物品交易系统

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 店铺管理 二手物品管理 广告管理 留言反馈 订单…