Mr. Cappuccino的第62杯咖啡——Spring之Bean的生命周期

news2024/11/25 12:49:49

Spring之Bean的生命周期

    • Aware接口
      • 项目结构
      • 项目代码
      • 运行结果
      • 源代码
      • 使用场景
    • InitializingBean接口
      • 项目结构
      • 项目代码
      • 运行结果
      • 源代码
    • BeanFactoryPostProcessor接口
      • 项目结构
      • 项目代码
      • 运行结果
      • 源代码
    • Bean的生命周期
      • 项目结构
      • 项目代码
      • 运行结果
      • 源代码

Aware接口

实现Aware接口是为了bean能获取某些信息、感知某些信息。Aware自身是一个空的接口,Spring提供了很多它的实现接口,开发者实现这些已有的接口就能获取特定的一些信息。

Spring提供了一些Aware接口的实现接口:
ApplicationContextAware、ApplicationEventPublisherAware、BeanClassLoaderAware、BeanFactoryAware、BeanNameAware、EmbeddedValueResolverAware、EnvironmentAware、ImportAware、LoadTimeWeaverAware、MessageSourceAware、NotificationPublisherAware、ResourceLoaderAware

项目结构

在这里插入图片描述

项目代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>spring-bean-life-cycle</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

AwareBean.java

package com.spring.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author honey
 * @date 2023-08-13 16:08:02
 */
public class AwareBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware {

    private String beanName;
    private ClassLoader classLoader;
    private ApplicationContext applicationContext;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public String getBeanName() {
        return beanName;
    }

    public ClassLoader getClassLoader() {
        return classLoader;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

SpringTest01.java

package com.spring.test;

import com.spring.bean.AwareBean;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-13 16:43:37
 */
public class SpringTest01 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("awareBean", AwareBean.class);
        applicationContext.refresh();
        AwareBean awareBean = applicationContext.getBean("awareBean", AwareBean.class);
        System.out.println("beanName:" + awareBean.getBeanName());
        System.out.println("classLoader:" + awareBean.getClassLoader());
        System.out.println("applicationContext:" + awareBean.getApplicationContext());
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


使用invokeAwareMethods方法处理部分Aware实现接口

AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

DefaultListableBeanFactory.java

在这里插入图片描述

AbstractBeanFactory.java

在这里插入图片描述

在这里插入图片描述

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


使用Bean对象后置处理器(ApplicationContextAwareProcessor)处理部分Aware实现接口

AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从AbstractApplicationContext类的finishBeanFactoryInitialization方法一直进入到AbstractAutowireCapableBeanFactory类的initializeBean方法,具体跳转步骤此处省略,可参照上面的跳转步骤

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ApplicationContextAwareProcessor.java

在这里插入图片描述

在这里插入图片描述


使用场景

SpringContextUtils.java

package com.bubble.core.util;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;

/**
 * Spring上下文工具类
 *
 * @author honey
 * @date 2021-09-21 18:27:54
 */
@Component
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpringContextUtils implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    public static <T> T getBean(String s, Class<T> clazz) {
        return context.getBean(s, clazz);
    }

    public static Boolean containsBean(String s) {
        return context.containsBean(s);
    }

    public static Boolean containsBean(Class<?> clazz) {
        String first = clazz.getSimpleName().substring(0, 1).toLowerCase();
        String after = clazz.getSimpleName().substring(1);
        return context.containsBean(first + after);
    }

    public static <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }

    public static void publishEvent(ApplicationEvent event) {
        context.publishEvent(event);
    }
}

InitializingBean接口

InitializingBean接口为bean对象提供了初始化方法,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。

Spring为bean对象提供了三种初始化方式:
1.在bean对象中实现InitializingBean接口;
2.使用@Bean注解注入bean对象时指定initMethod属性;
3.在bean对象的方法上使用@PostConstruct注解;

实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率要高一点,但是init-method方式消除了对spring的依赖。如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。

@PostConstruct通过Bean对象后置处理器(CommonAnnotationBeanPostProcessor)实现,InitializingBean和@Bean通过IOC工厂(BeanFactory)实现。

项目结构

在这里插入图片描述

项目代码

InitBean.java

package com.spring.bean;

import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;

/**
 * @author honey
 * @date 2023-08-13 18:41:58
 */
public class InitBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        System.out.println("InitBean 调用afterPropertiesSet()");
    }

    @PostConstruct
    public void init(){
        System.out.println("InitBean 调用init()");
    }

    public void initMethod(){
        System.out.println("InitBean 调用initMethod()");
    }
}

SpringConfig.java

package com.spring.config;

import com.spring.bean.InitBean;
import org.springframework.context.annotation.Bean;

/**
 * @author honey
 * @date 2023-08-13 18:52:09
 */
public class SpringConfig {

    @Bean(initMethod = "initMethod")
    public InitBean initBean() {
        return new InitBean();
    }
}

SpringTest02.java

package com.spring.test;

import com.spring.bean.InitBean;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-13 18:48:22
 */
public class SpringTest02 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("springConfig", SpringConfig.class);
        applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
        applicationContext.registerBean(ConfigurationClassPostProcessor.class);
        applicationContext.refresh();
        InitBean initBean = applicationContext.getBean("initBean", InitBean.class);
        System.out.println("InitBean " + initBean);
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


@PostConstruct通过Bean对象后置处理器(CommonAnnotationBeanPostProcessor)实现,底层使用反射技术。

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

CommonAnnotationBeanPostProcessor.java

在这里插入图片描述

InitDestroyAnnotationBeanPostProcessor.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


InitializingBean通过IOC工厂(BeanFactory)实现,底层没有使用反射技术。

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述


@Bean通过IOC工厂(BeanFactory)实现,底层使用反射技术。

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述


BeanFactoryPostProcessor接口

实现BeanFactoryPostProcessor接口,可以在Spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在Spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory。

ConfigurationClassPostProcessor:主要用于处理配置类,使@Bean、@Import、@ComponentScan等注解生效。

项目结构

在这里插入图片描述

项目代码

UserBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-14 01:02:08
 */
public class UserBean {

    private String name = "Faker";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

MyBeanFactoryPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author honey
 * @date 2023-08-14 01:00:25
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 修改bean对象的属性值
        BeanDefinition userBean = beanFactory.getBeanDefinition("userBean");
        userBean.getPropertyValues().addPropertyValue("name", "Honey");
    }
}

SpringTest03.java

package com.spring.test;

import com.spring.bean.UserBean;
import com.spring.processor.MyBeanFactoryPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-14 01:04:16
 */
public class SpringTest03 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("userBean", UserBean.class);
        applicationContext.registerBean(MyBeanFactoryPostProcessor.class);
        applicationContext.refresh();
        UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
        System.out.println("userBean name:" + userBean.getName());
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法

AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

PostProcessorRegistrationDelegate.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


修改bean对象的属性值

AbstractApplicationContext.java

在这里插入图片描述

具体跳转步骤此处省略

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


Bean的生命周期

Spring bean的生命周期主要包含四个阶段:实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction

Spring bean的生命周期核心代码:AbstractBeanFactory#getBean()

  1. 实例化Bean对象,执行构造方法;
  2. 属性赋值,对Bean对象中的属性进行赋值,如在Bean对象中使用@Autowired注解实现依赖注入以及通过BeanFactoryPostProcessor修改Bean对象中的属性值;
  3. 初始化阶段,执行Bean对象中Aware相关接口的实现方法;
  4. 初始化阶段,执行BeanPostProcessor#postProcessBeforeInitialization(),在初始化方法之前执行;
  5. 初始化阶段,执行初始化方法;
  6. 初始化阶段,执行BeanPostProcessor#postProcessAfterInitialization(),在初始化方法之后执行;
  7. 销毁Bean对象;
  1. 实例化Bean对象,当客户向容器请求一个尚未初始化的Bean对象时,或初始化Bean对象的时候需要注入另一个尚末初始化的依赖时,容器就会调用doCreateBean()方法进行实例化,实际上就是通过反射的方式创建出一个bean对象;
  2. Bean对象的实例创建完成后,接着就是给这个Bean对象进行属性填充,也就是注入这个Bean依赖的其它Bean对象;
  3. 属性填充完成后,初始化Bean对象,初始化阶段又可以分为几个步骤:
    3.1. 执行Bean对象中Aware相关接口的实现方法;
    3.2. Spring会检测Bean对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的某些资源。如实现BeanNameAware接口可以获取到BeanName,实现BeanFactoryAware接口可以获取到BeanFactory等等;
    3.3. 执行BeanPostProcessor的前置处理方法postProcessBeforeInitialization(),对Bean进行一些自定义的前置处理;
    3.4. 判断Bean是否实现了InitializingBean接口,如果实现了则会执行InitializingBean的afterPropertiesSet()进行初始化;
    3.5. 执行用户自定义的初始化方法,如init-method等;
    3.6. 执行BeanPostProcessor的后置处理方法postProcessAfterInitialization() ,对Bean进行一些自定义的后置处理;
  4. 初始化完成后,Bean对象就成功创建了,之后就可以使用这个Bean对象, 当Bean对象不再需要时,则会进行销毁操作;
    4.1. 首先判断Bean对象是否实现了DestructionAwareBeanPostProcessor接口,如果实现了则会执行DestructionAwareBeanPostProcessor后置处理器的销毁回调方法;
    4.2. 其次会判断Bean对象是否实现了DisposableBean接口,如果实现了将会调用其实现的destroy()方法;
    4.3. 最后判断这个Bean是否配置了dlestroy-method等自定义的销毁方法,如果是则会自动调用其配置的销毁方法;

项目结构

在这里插入图片描述

项目代码

AutowireBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-14 01:48:12
 */
public class AutowireBean {
}

LifeCycleBean.java

package com.spring.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author honey
 * @date 2023-08-14 01:47:44
 */
public class LifeCycleBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    public LifeCycleBean() {
        System.out.println("1.执行无参构造方法");
        System.out.println("LifeCycleBean 执行LifeCycleBean()");
    }

    @Autowired
    public void setAutowireBean(AutowireBean autowireBean) {
        System.out.println("2.设置对象属性");
        System.out.println("LifeCycleBean 执行setAutowireBean() autowireBean = " + autowireBean);
    }

    public void setName(String name) {
        System.out.println("2.设置对象属性");
        System.out.println("LifeCycleBean 执行setName() name = " + name);
        this.name = name;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setBeanName()");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setBeanClassLoader()");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setApplicationContext()");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行afterPropertiesSet()");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行postConstruct()");
    }

    public void initMethod() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行initMethod()");
    }

    @Override
    public void destroy() {
        System.out.println("7.执行销毁方法");
        System.out.println("LifeCycleBean 执行destroy()");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("7.执行销毁方法");
        System.out.println("LifeCycleBean 执行preDestroy()");
    }

    public String getName() {
        return name;
    }
}

LifeCycBeanFactoryPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author honey
 * @date 2023-08-14 02:13:45
 */
public class LifeCycBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 修改bean对象的属性值
        BeanDefinition userBean = beanFactory.getBeanDefinition("lifeCycleBean");
        userBean.getPropertyValues().addPropertyValue("name", "Honey");
    }
}

LifeCycleBeanPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @author honey
 * @date 2023-08-14 02:01:57
 */
public class LifeCycleBeanPostProcessor implements BeanPostProcessor {

    private final String beanName = "lifeCycleBean";

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("4.bean对象后置处理器初始化方法之前执行");
            System.out.println("LifeCycleBean 执行postProcessBeforeInitialization()");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("6.bean对象后置处理器初始化方法之后执行");
            System.out.println("LifeCycleBean 执行postProcessAfterInitialization()");
        }
        return bean;
    }
}

SpringConfig02.java

package com.spring.config;

import com.spring.bean.AutowireBean;
import com.spring.bean.LifeCycleBean;
import com.spring.processor.LifeCycBeanFactoryPostProcessor;
import com.spring.processor.LifeCycleBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

/**
 * @author honey
 * @date 2023-08-14 02:17:17
 */
@Import({LifeCycBeanFactoryPostProcessor.class, LifeCycleBeanPostProcessor.class})
public class SpringConfig02 {

    @Bean(initMethod = "initMethod")
    public LifeCycleBean lifeCycleBean() {
        return new LifeCycleBean();
    }

    @Bean
    public AutowireBean autowireBean() {
        return new AutowireBean();
    }
}

SpringTest04.java

package com.spring.test;

import com.spring.bean.LifeCycleBean;
import com.spring.config.SpringConfig02;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author honey
 * @date 2023-08-14 02:15:22
 */
public class SpringTest04 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
        LifeCycleBean lifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class);
        System.out.println("-----------------------------------");
        System.out.println("LifeCycleBean " + lifeCycleBean);
        System.out.println("-----------------------------------");
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码

AbstractBeanFactory.java

在这里插入图片描述
在这里插入图片描述

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


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

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

相关文章

Kotlin 中的 Lambda 与 Inline

在Kotlin中&#xff0c;有很多很酷很实用的特性&#xff0c;比如Lambda和高阶函数&#xff0c;利用这些特性&#xff0c;我们可以更加快速的实现开发&#xff0c;提升效率。 比如我们实现一个捕获Throwable&#xff0c;安全执行部分代码的高阶函数 fun safeRun(runnable: () …

最强自动化测试框架Playwright(26)-对话框

page.on(dialog) playwright 框架可以监听dialog事件&#xff0c;不管你alert 什么时候弹出来&#xff0c;监听到事件就自动处理了。 当出现 JavaScript 对话框时发出&#xff0c;例如alert、prompt或。侦听器必须dialog.accept()或dialog.dismiss()对话框 - 否则页面将冻结等…

Promise.all 静态方法

合并多个 Promise 对象&#xff0c;等待所有同时成功完成&#xff08;或某一个失败&#xff09;&#xff0c;做后续逻辑 语法&#xff1a; <script>const p Promise.all([Promise对象, Promise对象, ...])p.then(result > {// result 结果: [Promise对象成功结果, P…

mac出现java程序运行版本不一致

mac出现java程序运行版本不一致 Burpsuite_pro_v2022版本Burpsuite_pro_v2023.6.2版本解决方案&#xff1a; Burpsuite_pro_v2022版本 在安装BurpSuite的时候&#xff1a; 执行启动程序&#xff1a; java -noverify -javaagent:BurpSuiteLoader.jar -jar burpsuite_pro.jar运…

Windows Hyper-V Ubuntu 22.04 LTS安装

文章目录 UbuntuHyper-V启动 Ubuntu 下载Ubuntu-Desktop&#xff0c;这是个iso文件。 Hyper-V 启用虚拟化支持 services.msc 打开服务列表&#xff0c;关注Hyper-V服务是否启动 打开管理器 创建虚拟机 右键管理器》连接到服务器》连接到本地 快速创建 用到下载的ubu…

打造企业或者个人IP引流法

打造企业或者个人IP引流法. 大家好&#xff0c;我是百收网SEO编辑&#xff1a;狂潮老师&#xff0c;今天给大家分享企业IP打造的方法 首先我们想让人知道你的企业叫什么&#xff0c;怎么找到你的企业 这个时候我们就需要去各大平台发布信息&#xff0c;客户想了解直接去搜索…

JAVA多线程案例——实现三个窗口卖票功能

一、需求分析 利用多线程的思想模拟三个窗口售票员卖30张票的功能&#xff1a; 我们采用线程对象来模拟售票窗口&#xff0c;实现多个窗口同时卖票&#xff0c; 采用 Runnable 接口子类来模拟票数。 二、代码实现 1、继承 Thread 类的方式 class TicketWindow extends Threa…

【Unity】VS Code 没有智能提示 Unity 中的类

正常来说&#xff0c;VS Code中会对部分输入类名进行提示&#xff0c;如下图所述 假如你从Unity 中进入 VS Code后发现没有提示相关 Unity的类&#xff0c;可能是 Unity 中 有关于 VS Code的相关Package 没有跟着 VS Code升级到最新版本。 点击Unity Windows 下拉框中的 Pac…

分布式监控平台—zabbix

前言一、zabbix概述1.1 什么是zabbix1.2 zabbix的监控原理1.3 zabbix常见五个应用程序1.4 zabbix的监控模式1.5 监控架构1.5.1 C/S&#xff08;server—client&#xff09;1.5.2 server—proxy—client1.5.3 master—node—client 二、部署zabbix2.1 部署 zabbix server 端2.2 …

1.2 初识输入输出

博主介绍&#xff1a;爱打游戏的计算机专业学生 博主主页&#xff1a;夏驰和徐策 所属专栏&#xff1a;夏驰和徐策带你从零开始学C 前言&#xff1a; C语言并未定义任何输入输出 (IO) 语句&#xff0c;取而代之&#xff0c;包 含了一个全面的标准库 (standard library) 来 提…

分支语句与循环语句(2)

3.3 do...while()循环 3.3.1 do语句的语法&#xff1a; do 循环语句; while(表达式); 3.3.2执行流程图&#xff1a; 3.3.3 do语句的特点 循环至少执行一次&#xff0c;使用的场景有限&#xff0c;所以不是经常使用。 打印1-10的整数&#xff1a; #define _CRT_SECURE_NO_WA…

8年经验之谈 —— 如何做安全测试?

作为一名专业的安全测试人员&#xff0c;以下是一些关键步骤&#xff0c;可以帮助你更好地进行安全测试&#xff1a; 1. 了解应用程序: 深入了解应用程序的功能、架构和技术栈。这有助于你理解潜在的安全风险和漏洞。 2. 制定测试计划: 创建一个详细的测试计划&#xff0c;确…

【系统软件03】centos7安装和使用node-v18.16.0(centos7升级glibc 2.28)

【系统软件03】centos7安装和使用node-v18.16.0&#xff08;centos7升级glibc 2.28&#xff09; 前言&#xff1a;本文是解决node 18.16.0的依赖问题&#xff0c;具体的node安装流程&#xff0c;可以参考我的另外一篇文章。一、下载node v18.16.0二、下载glibc2.28&#xff08;…

如何轻松注册企业邮箱?快速掌握超简单的注册技巧!

随着互联网的发展&#xff0c;越来越多的企业开始使用电子邮件作为通信工具。企业邮箱不仅可以提高企业的工作效率&#xff0c;还可以使企业通信更加便捷、保密性更高。那么&#xff0c;企业邮箱怎么注册申请呢&#xff1f;下面我们来详细介绍一下。 第一步&#xff1a;选择邮箱…

百日筑基篇——python爬虫学习(一)

百日筑基篇——python爬虫学习&#xff08;一&#xff09; 文章目录 前言一、python爬虫介绍二、URL管理器三、所需基础模块的介绍1. requests2. BeautifulSoup1. HTML介绍2. 网页解析器 四、实操1. 代码展示2. 代码解释1. 将大文件划分为小的文件2. 获得结果页面的url3. 获取结…

第05天 SpringBoot自动配置原理

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

数学分析:曲线曲面积分

这一章还是很重要的&#xff0c;可以看到为什么dt1^dt2和dt1dt2是一样的。 可以看到&#xff0c;核心还是黎曼和&#xff0c;我们把两种微分的黎曼和都列出来&#xff0c;并且证明两个相等&#xff0c;即可。 这里要注意&#xff0c;微分形式的积分&#xff0c;在黎曼和的情况…

【解析postman工具的使用(基础篇】

postman前端请求详解 主界面1.常见类型的接口请求1.1 查询参数的接口请求1.1.1 什么是查询参数?1.1.2 postman如何请求 1.2 ❤表单类型的接口请求1.2.1 复习下http请求1.2.2❤ 什么是表单 1.3 上传文件的表单请求1.4❤ json类型的接口请求 2. 响应接口数据分析2.1 postman的响…

解决校园网使用vmware桥接模式,虚拟机与物理机互相ping通,但是虚拟机ping不通百度的问题

遇到的问题 使用校园网时&#xff0c;桥接模式下&#xff0c;物理机可以ping通虚拟机&#xff0c;但是虚拟机ping不通主机 解决方法 在物理机中查看网络相关信息 ipconfig 修改虚拟机网卡信息 vim /etc/sysconfig/network-scripts/ifcfg-ens33 注意 /ifcfg-ens33需要根据…

理解ConcurrentSkipListMap(有点类似于并发的TreeMap)

是一个分层的结构。 从最上面开始查找&#xff0c;最后层层往下查。 插入和删除有可能会引起节点Level的变更。 key是有序的&#xff0c;因此可以看做是并发的TreeMap