手写Spring:第9章-Aware感知容器对象

文章目录

  • 一、目标:Aware感知容器对象
  • 二、设计:Aware感知容器对象
  • 三、实现:Aware感知容器对象
    • 3.1 工程结构
    • 3.2 Spring感知接口类图
    • 3.3 定义标记接口和容器感知类
      • 3.3.1 定义标记接口
      • 3.3.2 对象工厂感知接口
      • 3.3.3 类加载感知接口
      • 3.3.4 对象名称感知接口
      • 3.3.5 应用上下文感知接口
    • 3.4 包装应用上下文处理器
      • 3.4.1 包装应用上下文处理器
      • 3.4.2 注册 BeanPostProcessor
    • 3.5 感知调用操作
      • 3.5.1 抽象对象工厂
      • 3.5.2 感知调用操作
  • 四、测试:Awrae感知容器对象
    • 4.1 修改UserDao用户对象
    • 4.2 单元测试
  • 五、总结:Aware感知容器对象

一、目标:Aware感知容器对象

💡 如何在获得 Spring 的功能时做些扩展框架的使用该怎么操作?

  • 目前实现的 Spring 框架中,在 Bean 操作上提供的能力,包括:
    • Bean 对象的定义和注册。
    • 操作 Bean 对象过程中执行的 BeanFactoryPostProcessorBeanFactoryPostProcessorInitializingBeanDisposableBean
  • XML 新增的一些配置处理,让我们可以对 Bean 对象有更强的操作性。
  • 那么,如果我们想获得 Spring 框架提供的 BeanFactoryApplicationContextBeanClassLoader 等这些功能做一些扩展框架的使用时该怎么操作呢?
    • 所以我们希望在 Spring 框架中提供一种能感知容器操作的接口,如果谁实现类这样的接口,就可以获取接口入参中的各类能力。

二、设计:Aware感知容器对象

💡 希望拿到 Spring 框架中一些提供的资源,那么首先需要考虑以一个什么方式去获取,之后定义出来的获取方式,在 Spring 该怎么去承接?
实现了这两项内容,就可以扩展出你需要的一些属于 Spring 框架本身的能力了。

  • Bean 对象实例化阶段我们操作过一些额外定义、属性、初始化和销毁的操作,其实如果像获取 Spring 一些如 BeanFactoryApplicationContext 时,也可以通过此类方式进行实现。
    • 需要定义一个标记性的接口,这个接口不需要有方法,它只起到标记作用。
    • 而具体的功能由继承此接口的其他功能性接口定义具体方法,最终这个接口就可以通过 instanceof 进行判断和调用。

在这里插入图片描述

  • 定义接口 Aware,在 Spring 框架中它是一种感知标记性接口,具体的子类定义和实现能感知容器中的相关对象。
    • 也就是通过这个桥梁,向具体的实现类中提供容器服务
  • 继承 Aware 的接口包括:BeanFactoryAwareBeanClassLoaderAwareBeanNameAwareApplicationContextAware
  • 在具体的接口实现过程中看到,
    • 一部分(BeanFactoryAwareBeanClassLoaderAwareBeanNameAware)在 factorysupport 文件夹下。
    • 另外(ApplicationContextAware)是在 contextsupport 中。
  • 这是因为不同的内容获取需要在不同的包下提供。所以:
    • AbstractApplicationContext 的具体实现中会用到向 beanFactory 添加 BeanPostProcessor 内容的 ApplicationContextAwareProcessor 操作。
    • 最后由 AbstractAutowireCapableBeanFactory 创建 createBean 时处理相应的调用操作。

三、实现:Aware感知容器对象

3.1 工程结构

spring-step-08
|-src|-main|	|-java|		|-com.lino.springframework|			|-beans|			|	|-factory|			|	|	|-config|			|	|	|	|-AutowireCapableBeanFactory.java|			|	|	|	|-BeanDefinition.java|			|	|	|	|-BeanFactoryPostProcessor.java|			|	|	|	|-BeanPostProcessor.java|			|	|	|	|-BeanReference.java|			|	|	|	|-ConfigurableBeanFactory.java|			|	|	|	|-SingletonBeanRegistry.java|			|	|	|-support|			|	|	|	|-AbstractAutowireCapableBeanFactory.java|			|	|	|	|-AbstractBeabDefinitionReader.java|			|	|	|	|-AbstractBeabFactory.java|			|	|	|	|-BeabDefinitionReader.java|			|	|	|	|-BeanDefinitionRegistry.java|			|	|	|	|-CglibSubclassingInstantiationStrategy.java|			|	|	|	|-DefaultListableBeanFactory.java|			|	|	|	|-DefaultSingletonBeanRegistry.java|			|	|	|	|-DisposableBeanAdapter.java|			|	|	|	|-InstantiationStrategy.java|			|	|	|	|-SimpleInstantiationStrategy.java|			|	|	|-support|			|	|	|	|-XMLBeanDefinitionReader.java|			|	|	|-Aware.java|			|	|	|-BeanClassLoaderAware.java|			|	|	|-BeanFactory.java|			|	|	|-BeanFactoryAware.java|			|	|	|-BeanNameAware.java|			|	|	|-ConfigurableListableBeanFactory.java|			|	|	|-DisposableBean.java|			|	|	|-HierarcgicalBeanFactory.java|			|	|	|-InitializingBean.java|			|	|	|-ListableBeanFactory.java|			|	|-BeansException.java|			|	|-PropertyValue.java|			|	|-PropertyValues.java|			|-context|			|	|-support|			|	|	|-AbstractApplicationContext.java|			|	|	|-AbstractRefreshableApplicationContext.java|			|	|	|-AbstractXmlApplicationContext.java|			|	|	|-ApplicationContextAwareProcessor.java|			|	|	|-ClassPathXmlApplicationContext.java|			|	|-ApplicationContext.java|			|	|-ApplicationContextAware.java|			|	|-ConfigurableApplicationContext.java|			|-core.io|			|	|-ClassPathResource.java|			|	|-DefaultResourceLoader.java|			|	|-FileSystemResource.java|			|	|-Resource.java|			|	|-ResourceLoader.java|			|	|-UrlResource.java|			|-util|			|	|-ClassUtils.java|-test|-java|-com.lino.springframework.test|-bean|	|-UserDao.java|	|-UserService.java|-ApiTest.java|-resources|-spring.xml

3.2 Spring感知接口类图

在这里插入图片描述

  • 整个类关系就是关于 Aware 感知的定义和对容器感知的实现。
  • Aware 有四个继承的接口,其他这些接口的继承都是为了继承一个标记,有了标记的存在更方便类的操作和具体判断实现。
  • 另外由于 ApplicationContext 并不是在 AbstractAutowireCapableBeanFactorycreateBean 方法下的内容。
    • 所以需要像容器中注册 addBeanPostProcessor,再由 createBean 统一调用 applyBeanPostProcessorBeforeInitialization 时进行操作。

3.3 定义标记接口和容器感知类

3.3.1 定义标记接口

Aware.java

package com.lino.springframework.beans.factory;/*** @description: 标记类接口,实现该接口可以被Spring容器感知*/
public interface Aware {
}
  • Spring 中有特别多类似这样的标记接口的设计方式,它们的存在就像是一种标签一样,可以方便统一摘取出属于此类接口的实现类,通常会有 instanceof 一起判断使用。

3.3.2 对象工厂感知接口

BeanFactoryAware.java

package com.lino.springframework.beans.factory;import com.lino.springframework.beans.BeansException;/*** @description: 实现此接口,即能感知到所属的 BeanFactory*/
public interface BeanFactoryAware extends Aware {/*** 设置对象工厂** @param beanFactory 对象工厂* @throws BeansException 异常*/void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
  • 实现此接口,即能感知到所属的 BeanFactory

3.3.3 类加载感知接口

BeanClassLoaderAware.java

package com.lino.springframework.beans.factory;/*** @description: 实现此接口,即能感知到所属的 ClassLoader*/
public interface BeanClassLoaderAware extends Aware {/*** 设置类加载器** @param classLoader 类加载器*/void setBeanClassLoader(ClassLoader classLoader);
}
  • 实现此接口,即能感知到所属的 ClassLoader

3.3.4 对象名称感知接口

BeanNameAware.java

package com.lino.springframework.beans.factory;/*** @description: 实现此接口,即能感知到所属的 BeanName*/
public interface BeanNameAware {/*** 设置对象名称** @param name 对象名称*/void setBeanName(String name);
}
  • 实现此接口,即能感知到所属的 BeanName

3.3.5 应用上下文感知接口

ApplicationContextAware.java

package com.lino.springframework.context;import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.factory.Aware;/*** @description: 实现此接口,即能感知到所属的 ApplicationContext*/
public interface ApplicationContextAware extends Aware {/*** 设置应用上下文** @param applicationContext 应用上下文* @throws BeansException 异常*/void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
  • 实现此接口,即能感知到所属的 ApplicationContext

3.4 包装应用上下文处理器

3.4.1 包装应用上下文处理器

ApplicationContextAwareProcessor.java

package com.lino.springframework.context.support;import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.factory.config.BeanPostProcessor;
import com.lino.springframework.context.ApplicationContext;
import com.lino.springframework.context.ApplicationContextAware;/*** @description: 通过 BeanPostProcessor 实现类感知应用上下文对象*/
public class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ApplicationContext applicationContext;public ApplicationContextAwareProcessor(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(applicationContext);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
  • 由于 ApplicationContext 的获取并不能直接在创建 Bean 时候就可以拿到,所以需要在 refresh 操作时,把 ApplicationContext 写入到一个包装的 BeanPostProcessor 中去,再由 AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization 方法调用。

3.4.2 注册 BeanPostProcessor

AbstractApplicationContext.java

package com.lino.springframework.context.support;import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.factory.ConfigurableListableBeanFactory;
import com.lino.springframework.beans.factory.config.BeanFactoryPostProcessor;
import com.lino.springframework.beans.factory.config.BeanPostProcessor;
import com.lino.springframework.context.ConfigurableApplicationContext;
import com.lino.springframework.core.io.DefaultResourceLoader;
import java.util.Map;/*** @description: 抽象应用上下文*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {@Overridepublic void refresh() throws BeansException {// 1.创建 BeanFactory,并加载 BeanDefinitionrefreshBeanFactory();// 2.获取 BeanFactoryConfigurableListableBeanFactory beanFactory = getBeanFactory();// 3.添加 ApplicationContextAwareProcessor,让继承自 ApplicationContextAware 的 Bean 对象都能感知所属的 ApplicationContextbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 4.在 Bean 实例化之前,执行 BeanFactoryPostProcessinvokeBeanFactoryPostProcessor(beanFactory);// 5.BeanPostProcessor 需要提前与其他 Bean 对象实例化之前执行注册操作registerBeanPostProcessor(beanFactory);// 6.提前实例化单例 Bean 对象beanFactory.preInstantiateSingletons();}...
}
  • refresh() 方法就是整个 Spring 容器的操作过程,这次新增加了 addBeanPostProcessor 操作。
  • 添加 ApplicationContextAwareProcessor,让继承自 ApplicationContextAwareBean 对象都能感知所属的 ApplicationContext

3.5 感知调用操作

3.5.1 抽象对象工厂

AbstractBeanFactory.java

package com.lino.springframework.beans.factory.support;import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.factory.config.BeanDefinition;
import com.lino.springframework.beans.factory.config.BeanPostProcessor;
import com.lino.springframework.beans.factory.config.ConfigurableBeanFactory;
import com.lino.springframework.util.ClassUtils;
import java.util.ArrayList;
import java.util.List;/*** @description: 抽象的 Bean 工厂基类,定义模板方法*/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();...public ClassLoader getBeanClassLoader() {return this.beanClassLoader;}
}
  • 添加 ClassLoader 对像,并提供一个获取对象类加载器的方法。getBeanClassLoader()

3.5.2 感知调用操作

AbstractAutowireCapableBeanFactory.java

package com.lino.springframework.beans.factory.support;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.PropertyValue;
import com.lino.springframework.beans.PropertyValues;
import com.lino.springframework.beans.factory.*;
import com.lino.springframework.beans.factory.config.AutowireCapableBeanFactory;
import com.lino.springframework.beans.factory.config.BeanDefinition;
import com.lino.springframework.beans.factory.config.BeanPostProcessor;
import com.lino.springframework.beans.factory.config.BeanReference;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;/*** @description: 实现默认bean创建的抽象bean工厂超类* @author: lingjian* @createDate: 2022/11/22 14:39*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();...private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {// invokeAwareMethodsif (bean instanceof Aware) {if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(this);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}}// 1.执行 BeanPostProcessor Before 处理Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);// 执行 Bean 对象的初始化方法try {invokeInitMethods(beanName, wrappedBean, beanDefinition);} catch (Exception e) {throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);}// 2.执行 BeanPostProcessor After 处理wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);return wrappedBean;}...
}
  • 首先在 initializeBean 中,通过判断 bean instanceof Aware,调用三个接口方法。这样就能通知到已经实现了此接口的类。
    • ((BeanFactoryAware) bean).setBeanFactory(this)
    • ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader())
    • ((BeanNameAware) bean).setBeanName(beanName)
  • 另外还向 BeanPostProcessor 中添加了 ApplicationContextAwareProcessor,此时在这个方法中也会被调用到具体的类实现,得到一个 ApplicationContext 属性。

四、测试:Awrae感知容器对象

4.1 修改UserDao用户对象

UserService.java

package com.lino.springframework.test.bean;import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.factory.*;
import com.lino.springframework.context.ApplicationContext;
import com.lino.springframework.context.ApplicationContextAware;/*** @description: 模拟用户 Bean 对象*/
public class UserService implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware {private ApplicationContext applicationContext;private BeanFactory beanFactory;private String uId;private String company;private String location;private UserDao userDao;@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("ClassLoader: " + classLoader);}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}@Overridepublic void setBeanName(String name) {System.out.println("Bean Name is: " + name);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 查询用户信息*/public String queryUserInfo() {return userDao.queryUserName(uId) + "," + company + "," + location;}public String getuId() {return uId;}public void setuId(String uId) {this.uId = uId;}public String getCompany() {return company;}public void setCompany(String company) {this.company = company;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}public ApplicationContext getApplicationContext() {return applicationContext;}public BeanFactory getBeanFactory() {return beanFactory;}
}
  • 新增加 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 四个感知的实现类,并在类中的实现相应的接口方法。

4.2 单元测试

ApiTest.java

@Test
public void test_xml() {// 1.初始化 BeanFactoryClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");applicationContext.registerShutdownHook();// 2.获取Bean对象调用方法UserService userService = applicationContext.getBean("userService", UserService.class);String result = userService.queryUserInfo();System.out.println("测试结果:" + result);System.out.println("ApplicationContextAware: " + userService.getApplicationContext());System.out.println("BeanFactoryAware: " + userService.getBeanFactory());
}
  • 测试方法中添加了一写关于新增 Aware 实现的调用,其他不需要调用的也打印了相应的日志信息,可以在测试结果中看到。

测试结果

执行:init-method
ClassLoader: sun.misc.Launcher$AppClassLoader@18b4aac2
Bean Name is: userService
测试结果:张三,阿里,杭州
ApplicationContextAware: com.lino.springframework.context.support.ClassPathXmlApplicationContext@56cbfb61
BeanFactoryAware: com.lino.springframework.beans.factory.support.DefaultListableBeanFactory@1134affc
执行:destroy-method
  • 从测试结果来看,新增加的感知接口对应的具体实现(BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware),已经可以正常输出结果。

五、总结:Aware感知容器对象

  • 本节关于 Aware 的感知接口的四个继承接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 的实现,又扩展了 Spring 的功能。
  • 目前关于 Spring 框架的实现中,功能已经越来越趋向于完整,尤其对于 Bean 对象的生命周期。
    在这里插入图片描述

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

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

相关文章

Java“牵手”唯品会商品详情数据,唯品会商品详情API接口,唯品会API接口申请指南

唯品会平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取唯品会商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xff0c;…

大数据Flink(七十四):SQL的滑动窗口(HOP)

文章目录 SQL的滑动窗口(HOP) SQL的滑动窗口(HOP) 滑动窗口定义:滑动窗口也是将元素指定给固定长度的窗口。与滚动窗口功能一样,也有窗口大小的概念。不一样的地方在于,滑动窗口有另一个参数控制窗口计算的频率(滑动窗口滑动的步长)。因此,如果滑动的步长小于窗口大…

UNext:基于 MLP 的快速医学图像分割网络

UNext 会议分析摘要贡献方法整体框架1.Shifted MLP2.Tokenized MLP Stage 实验1.对比实验2.消融实验2.1 模块的消融实验2.2 通道数的探索 可借鉴参考 会议分析 期刊&#xff08;会议&#xff09;名&#xff1a; MICCAI 2022 会议信息&#xff1a; 属于顶会了 有代码&#xff1…

【经验分享】如何使用VSCode对比两个文件

问题&#xff1a; 当有两个不同版本的文件&#xff0c;如何使用VSCode对比两个文件 解决办法 长按ctrl选择想要对比的两个文件-----右键选择将已选项进行比较----大功告成 大功告成

【LangChain系列 4】Model I/O——Prompts概述

原文地址&#xff1a;【LangChain系列 4】Model I/O——Prompts概述 本文速读&#xff1a; Prompt模版 样本选择器 Prompts简单来讲就是一组指令或文本输入&#xff0c;语言模型理解它的意思后&#xff0c;给出一个输出响应。 LangChain提供了一些模块可以让我们更方便地使…

vue 分页器组件+css动画效果

全网都找了一遍没有找到符合UI需求的分页动画&#xff0c;于是就主动上手了 需求&#xff1a; 1、分页最多显示9页&#xff0c;总页数最多显示无上限&#xff1b; 2、点击下一页的时候需要有动画效果过度&#xff0c;如果当前页数是当前显示最后的一页&#xff0c;则停了当前…

算法训练day36|贪心算法 part05(重叠区间三连击:LeetCode435. 无重叠区间763.划分字母区间56. 合并区间)

文章目录 435. 无重叠区间思路分析 763.划分字母区间思路分析代码实现思考总结 56. 合并区间思路分析 435. 无重叠区间 题目链接&#x1f525;&#x1f525; 给定一个区间的集合&#xff0c;找到需要移除区间的最小数量&#xff0c;使剩余区间互不重叠。 注意: 可以认为区间的…

第3章 【MySQL】字符集和比较规则

3.1 字符集和比较规则简介 3.1.1 字符集简介 如何存储字符串&#xff1f;需要建立字符与二进制数据的映射关系。建立这个关系需要&#xff1a; 1.把哪些字符映射成二进制数据&#xff1f; 2.怎么映射&#xff1f; 将一个字符映射成一个二进制数据的过程也叫做 编码 &#…

mybatis源码学习-3-解析器模块

1. 目录结构 XNode类&#xff1a; 作用&#xff1a;XNode 类表示XML文档中的一个节点&#xff08;Element或Node&#xff09;&#xff0c;它用于封装XML节点的信息&#xff0c;例如标签名、属性和子节点等。使用场景&#xff1a;MyBatis使用 XNode 来解析XML配置文件中的各种元…

长胜证券:资本市场的含义是什么?

本钱商场是指企业和政府通过证券生意来筹集资金并进行出资活动的商场。本钱商场通常被分为两个部分&#xff1a;初级商场和二级商场。初级商场是新证券发行的商场&#xff0c;而二级商场则是已发行证券的生意商场。本钱商场的展开程度是一个国家经济展开的重要目标之一。 从宏…

详解Transformer中的Encoder

一.Transformer架构 左半边是Encoder&#xff0c;右半边是Decoder。 二.Vision Transformer Vision Transformer取了Transformer的左半边。包含 Input EmbeddingPositional Encoding多头注意力机制 Add & Norm(前馈网络)Feed Forward Add & Norm 2.1 Input Embe…

企业架构LNMP学习笔记4

企业服务器LNMP环境搭建&#xff1a; 常见的软件架构&#xff1a; 1&#xff09;C/S: client/server 2&#xff09;B/S: browser/server 不管是C还是B&#xff0c;都是属于客户端属于前端。那么运维人员主要是负责和管理的Server端&#xff0c;也统称为服务器端。为了快速的…

RetroArch 接入两个同款手柄只能识别到一个导致无法双打的问题

测试平台 设备:StationPC M3 RetroArch: 1.1.5(当前官方最新) 手柄:北通蝙蝠BD2F(XBOX360键位) 问题说明 RetroArch插入两个同款手柄/摇杆时只能识别到一个&#xff0c;此时两个手柄都是可以控制模拟器&#xff0c;但是进入游戏也都是p1&#xff0c;无法实现双打 解决办法 …

Window安装虚拟机+给虚拟机安装Linux

一、虚拟机下载 这里使用Virtualbox虚拟机。可以直接从官网下载&#xff1a;Downloads – Oracle VM VirtualBox 点击进行下载&#xff0c;选择window版本的。直接双击&#xff0c;一直下一步 进行安装 PS&#xff1a;安装需要开启CPU虚拟化&#xff0c;一般电脑都已经开启了…

最新社区团购电商小程序源码 无bug完美运营版+详细搭建部署教程

分享一个开源社区团购电商小程序源码&#xff0c;无bug完美运营版&#xff0c;含完整前后端详细搭建部署教程。 系统运营模式&#xff1a;整合线下社区资源&#xff0c;由各快递代收点、社区便利店、社区物业、业主等发起的社区微信群&#xff0c;推送商品信息&#xff0c;消费…

【数据恢复】.360勒索病毒|金蝶、用友、OA、ERP等软件数据库恢复

引言&#xff1a; 在当今数字化的时代&#xff0c;网络犯罪已经演变成了一场全球性的威胁&#xff0c;而 360 勒索病毒则是其中最为可怕和具有破坏性的威胁之一。这种恶意软件以其危害深远、难以防范的特点而令人震惊。本文91数据恢复将深入探讨 360 勒索病毒的可怕性&#xff…

sql:SQL优化知识点记录(九)

&#xff08;1&#xff09;小表驱动大表 对sql调优的分析&#xff1a; 排序优化&#xff1a; 数据库的连接方式&#xff0c;里面的数据尽量这样连接&#xff0c;尽量选择第一个方式&#xff0c;因为两个表的连接一共建立5次连接&#xff0c;第二个建立1000次连接&#xff0c;从…

使用spring自带的发布订阅机制来实现消息发布订阅

背景 公司的项目以前代码里面有存在使用spring自带发布订阅的代码&#xff0c;因此稍微学习一下如何使用&#xff0c;并了解一下这种实现方式的优缺点。 优点 实现方便&#xff0c;代码方面基本只需要定义消息体和消费者&#xff0c;适用于小型应用程序。不依赖外部中间件&a…

h5微传单制作教程:快速轻松制作

在当今社交媒体充斥的时代&#xff0c;微传单作为一种新型的宣传推广方式&#xff0c;成为了企业和个人在传播信息时的重要工具。h5微传单相比传统的纸质传单更加灵活多样&#xff0c;并且能够通过手机、平板等设备随时随地进行浏览和分享&#xff0c;具有很高的传播效果。下面…

SpringMVC_SSM整合

一、回顾SpringMVC访问接口流程 1.容器加载分析 容器分析 手动注册WebApplicationContext public class ServletConfig extends AbstractDispatcherServletInitializer {Overrideprotected WebApplicationContext createServletApplicationContext() {//获取SpringMVC容器An…