SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(二)

news/2024/4/26 22:43:40/文章来源:https://blog.csdn.net/A_art_xiang/article/details/129110375

文章目录

  • 系列文档索引
  • 四、Spring AOP的使用入门
    • 1、激活AspectJ模块
      • (1)注解激活
      • (2)XML激活
    • 2、创建 @AspectJ 代理(了解)
      • (1)编程方式创建 @AspectJ 代理实例
      • (2)XML 配置创建 AOP 代理
      • (3)标准代理工厂 API
    • 3、Pointcut 使用
      • (1)Pointcut 指令与表达式
      • (2)XML 配置 Pointcut
      • (3)API 实现 Pointcut
    • 4、拦截动作
      • (1)注解方式实现
      • (2)XML配置方式实现
      • (3)API方式实现
      • (4)同一个@Before执行顺序
  • 未完待续
  • 参考资料

系列文档索引

SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(一)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(二)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(三)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(四)

四、Spring AOP的使用入门

1、激活AspectJ模块

激活AspectJ模块分两种方式,一种是使用注解方式,一种使用xml方式。

• 注解激活 - @EnableAspectJAutoProxy
• XML 配置 - <aop:aspectj-autoproxy/>

(1)注解激活

import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Aspect        // 声明为 Aspect 切面
@Configuration // Configuration class
@EnableAspectJAutoProxy // 激活 Aspect 注解自动代理
public class AspectJAnnotationDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AspectJAnnotationDemo.class);context.refresh();AspectJAnnotationDemo aspectJAnnotationDemo = context.getBean(AspectJAnnotationDemo.class);System.out.println(aspectJAnnotationDemo.getClass());context.close();}
}

以上是使用注解激活的实例,使用@EnableAspectJAutoProxy即可激活Aspect注解自动代理。

该AspectJAnnotationDemo类使用@Configuration标注代表是一个配置类,Spring中的配置类都会被代理,默认是使用CGLIB代理。

@Aspect表示该类是一个切面类。

(2)XML激活

在xml文件中使用该标签,即可激活Aspect自动代理:

<aop:aspectj-autoproxy/>

该标签与注解的@EnableAspectJAutoProxy效果相同。

2、创建 @AspectJ 代理(了解)

(1)编程方式创建 @AspectJ 代理实例

实现类: org.springframework.aop.aspectj.annotation.AspectJProxyFactory

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.aop.framework.AopContext;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class AspectJAnnotationUsingAPIDemo {public static void main(String[] args) {// 通过创建一个 HashMap 缓存,作为被代理对象Map<String, Object> cache = new HashMap<>();// 创建 Proxy 工厂(AspectJ)AspectJProxyFactory proxyFactory = new AspectJProxyFactory(cache);// 增加 Aspect 配置类,暂时不需要
//        proxyFactory.addAspect(AspectConfiguration.class);// 设置暴露代理对象到 AopContextproxyFactory.setExposeProxy(true);proxyFactory.addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {Object proxy = AopContext.currentProxy();System.out.printf("[MethodBeforeAdvice] 当前存放是 Key: %s , Value : %s ," +"代理对象:%s\n", args[0], args[1], proxy);}}});// 添加 AfterReturningAdviceproxyFactory.addAdvice(new AfterReturningAdvice() {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target)throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {System.out.printf("[AfterReturningAdvice] 当前存放是 Key: %s , 新存放的 Value : %s , 之前关联的 Value : %s\n ",args[0],    // keyargs[1],    // new valuereturnValue // old value);}}});// 通过代理对象存储数据Map<String, Object> proxy = proxyFactory.getProxy();proxy.put("1", "A");proxy.put("1", "B");System.out.println(cache.get("1"));}
}

(2)XML 配置创建 AOP 代理

<aop:aspectj-autoproxy/><bean id="echoService" class="com.demo.DefaultEchoService"></bean><!--拦截器-->
<bean id="echoServiceMethodInterceptor"class="com.demo.interceptor.EchoServiceMethodInterceptor"/><bean id="echoServiceProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="targetName" value="echoService"/> <!--指定targetName为需要代理的bean的Id--><property name="interceptorNames"> <!--指定拦截器--><value>echoServiceMethodInterceptor</value></property>
</bean>
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;@Aspect        // 声明为 Aspect 切面
@Configuration // Configuration class
public class ProxyFactoryBeanDemo {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-aop-context.xml");EchoService echoService = context.getBean("echoServiceProxyFactoryBean", EchoService.class);System.out.println(echoService.echo("Hello,World"));System.out.println(echoService.getClass());context.close();}
}

我们发现,这种方式与编程的方式创建代理是差不多的,只不过是对象的创建交给Spring来处理了。

(3)标准代理工厂 API

实现类 - org.springframework.aop.framework.ProxyFactory

上面XML配置的方式创建ProxyFactoryBean,更多用于Spring中的应用,而ProxyFactory更偏底层。

import org.springframework.aop.framework.ProxyFactory;/*** ProxyFactory使用示例*/
public class ProxyFactoryDemo {public static void main(String[] args) {DefaultEchoService defaultEchoService = new DefaultEchoService();// 注入目标对象(被代理)ProxyFactory proxyFactory = new ProxyFactory(defaultEchoService);//proxyFactory.setTargetClass(DefaultEchoService.class);// 添加 Advice 实现 MethodInterceptor < Interceptor < AdviceproxyFactory.addAdvice(new EchoServiceMethodInterceptor());// 获取代理对象EchoService echoService = (EchoService) proxyFactory.getProxy();System.out.println(echoService.echo("Hello,World"));}
}
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}

3、Pointcut 使用

Spring中的Pointcut只支持方法级别的定义,也就是说只支持Bean的方法拦截。

Pointcut 只是一个筛选,并没有具体的动作。
Advice才是具体的动作,一个Pointcut 可以对应多个Advice。

(1)Pointcut 指令与表达式

Spring AOP 之 aspect表达式详解

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** Pointcut 示例*/
@Configuration // Configuration class
@EnableAspectJAutoProxy // 激活 Aspect 注解自动代理
public class AspectJAnnotatedPointcutDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AspectJAnnotatedPointcutDemo.class,AspectConfiguration.class);context.refresh();AspectJAnnotatedPointcutDemo aspectJAnnotationDemo = context.getBean(AspectJAnnotatedPointcutDemo.class);aspectJAnnotationDemo.execute();context.close();}public void execute() {System.out.println("execute()...");}
}
/*** Aspect 配置类*/
@Aspect
public class AspectConfiguration {@Pointcut("execution(public * *(..))") // 匹配 Join Pointprivate void anyPublicMethod() { // 方法名即 Pointcut 名System.out.println("@Pointcut at any public method."); // 方法通常设置为空的,不会有具体的动作}@Before("anyPublicMethod()")          // Join Point 拦截动作public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}}

Pointcut定义在切面类的私有方法上,该方法没有任何的动作,只是筛选要切入的方法。该方法名即为Pointcut名。

(2)XML 配置 Pointcut

<!--定义配置类-->
<bean id="aspectXmlConfig" class="com.demo.AspectXmlConfig"/><aop:config><aop:aspect id="AspectXmlConfig" ref="aspectXmlConfig"><!--引用配置类--><aop:pointcut id="anyPublicMethod" expression="execution(public * *(..))"/><!--Pointcut--><aop:before method="beforeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><!--配置类的方法--></aop:aspect>
</aop:config>
public class AspectXmlConfig {public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}
}

(3)API 实现 Pointcut

核心 API - org.springframework.aop.Pointcut
• org.springframework.aop.ClassFilter
• org.springframework.aop.MethodMatcher

适配实现 - DefaultPointcutAdvisor

public static void main(String[] args) {EchoServicePointcut echoServicePointcut = new EchoServicePointcut("echo", EchoService.class);// 将 Pointcut 适配成 AdvisorDefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(echoServicePointcut, new EchoServiceMethodInterceptor());DefaultEchoService defaultEchoService = new DefaultEchoService();ProxyFactory proxyFactory = new ProxyFactory(defaultEchoService);// 添加 AdvisorproxyFactory.addAdvisor(advisor);// 获取代理对象EchoService echoService = (EchoService) proxyFactory.getProxy();System.out.println(echoService.echo("Hello,World"));
}
public class EchoServicePointcut extends StaticMethodMatcherPointcut {private String methodName;private Class targetClass;public EchoServicePointcut(String methodName, Class targetClass) {this.methodName = methodName;this.targetClass = targetClass;}@Overridepublic boolean matches(Method method, Class<?> targetClass) {return Objects.equals(methodName, method.getName())&& this.targetClass.isAssignableFrom(targetClass);}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public Class getTargetClass() {return targetClass;}public void setTargetClass(Class targetClass) {this.targetClass = targetClass;}
}
public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}

4、拦截动作

Around环绕动作。

Before前置动作。

After后置动作:
• 方法返回后:AfterReturning
• 异常发生后:AfterThrowing
• finally 执行:After

(1)注解方式实现

@Aspect
@Order
public class AspectConfiguration {@Pointcut("execution(public * *(..))") // 匹配 Join Pointprivate void anyPublicMethod() { // 方法名即 Pointcut 名System.out.println("@Pointcut at any public method.");}@Around("anyPublicMethod()")         // Join Point 拦截动作public Object aroundAnyPublicMethod(ProceedingJoinPoint pjp) throws Throwable {System.out.println("@Around any public method.");return pjp.proceed();}@Before("anyPublicMethod()")          // Join Point 拦截动作public void beforeAnyPublicMethod() {Random random = new Random();if (random.nextBoolean()) {throw new RuntimeException("For Purpose.");}System.out.println("@Before any public method.");}@After("anyPublicMethod()")public void finalizeAnyPublicMethod() {System.out.println("@After any public method.");}@AfterReturning("anyPublicMethod()")// AspectJAfterReturningAdvice is AfterReturningAdvice// 一个 AfterReturningAdviceInterceptor 关联一个 AfterReturningAdvice// Spring 封装 AfterReturningAdvice -> AfterReturningAdviceInterceptor// AfterReturningAdviceInterceptor is MethodInterceptor// AfterReturningAdviceInterceptor//  -> AspectJAfterReturningAdvice//      -> AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgspublic void afterAnyPublicMethod() {System.out.println("@AfterReturning any public method.");}@AfterThrowing("anyPublicMethod()")public void afterThrowingAnyPublicMethod() {System.out.println("@AfterThrowing any public method");}public String toString() {return "AspectConfiguration";}private int getValue() {return 0;}
}

(2)XML配置方式实现

<aop:config><!--        <aop:pointcut id="allPointcut" expression="execution(* * *(..))"/>--><aop:aspect id="AspectXmlConfig" ref="aspectXmlConfig"><aop:pointcut id="anyPublicMethod" expression="execution(public * *(..))"/><aop:around method="aroundAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:around method="aroundAnyPublicMethod" pointcut="execution(public * *(..))"/><aop:before method="beforeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:before method="beforeAnyPublicMethod" pointcut="execution(public * *(..))"/><aop:after method="finalizeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:after-returning method="afterAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:after-throwing method="afterThrowingAnyPublicMethod" pointcut-ref="anyPublicMethod"/></aop:aspect>
</aop:config>
public class AspectXmlConfig {public Object aroundAnyPublicMethod(ProceedingJoinPoint pjp) throws Throwable {Random random = new Random();if (random.nextBoolean()) {throw new RuntimeException("For Purpose from XML configuration.");}System.out.println("@Around any public method : " + pjp.getSignature());return pjp.proceed();}public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}public void finalizeAnyPublicMethod() {System.out.println("@After any public method.");}public void afterAnyPublicMethod() {System.out.println("@AfterReturning any public method.");}public void afterThrowingAnyPublicMethod() {System.out.println("@AfterThrowing any public method.");}
}

(3)API方式实现

为什么 Spring AOP 不需要设计 Around Advice
• AspectJ @Around 与 org.aspectj.lang.ProceedingJoinPoint 配合执行被代理方法
• ProceedingJoinPoint#proceed() 方法类似于 Java Method#invoke(Object,Object…)
• Spring AOP 底层 API ProxyFactory 可通过 addAdvice 方法与 Advice 实现关联
• 接口 Advice 是 Interceptor 的父亲接口,而接口 MethodInterceptor 又扩展了 Interceptor
• MethodInterceptor 的invoke 方法参数 MethodInvocation 与 ProceedingJoinPoint 类似

API 实现 Before Advice

核心接口 - org.springframework.aop.BeforeAdvice

类型:标记接口,与 org.aopalliance.aop.Advice 类似

方法 JoinPoint 扩展 - org.springframework.aop.MethodBeforeAdvice

接受对象 - org.springframework.aop.framework.AdvisedSupport
• 基础实现类 - org.springframework.aop.framework.ProxyCreatorSupport
• 常见实现类:org.springframework.aop.framework.ProxyFactory;org.springframework.aop.framework.ProxyFactoryBean;org.springframework.aop.aspectj.annotation.AspectJProxyFactory

API 实现三种 After Advice

核心接口 - org.springframework.aop.AfterAdvice

类型:标记接口,与 org.aopalliance.aop.Advice 类似

扩展
• org.springframework.aop.AfterReturningAdvice
• org.springframework.aop.ThrowsAdvice

接受对象 - org.springframework.aop.framework.AdvisedSupport
• 基础实现类 - org.springframework.aop.framework.ProxyCreatorSupport
• 常见实现类:org.springframework.aop.framework.ProxyFactory;org.springframework.aop.framework.ProxyFactoryBean;org.springframework.aop.aspectj.annotation.AspectJProxyFactory

// 通过创建一个 HashMap 缓存,作为被代理对象
Map<String, Object> cache = new HashMap<>();
// 创建 Proxy 工厂(AspectJ)
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(cache);
// 增加 Aspect 配置类,此处不需要
// proxyFactory.addAspect(AspectConfiguration.class);
// 设置暴露代理对象到 AopContext
proxyFactory.setExposeProxy(true);
proxyFactory.addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {Object proxy = AopContext.currentProxy();System.out.printf("[MethodBeforeAdvice] 当前存放是 Key: %s , Value : %s ," +"代理对象:%s\n", args[0], args[1], proxy);}}
});// 添加 AfterReturningAdvice
proxyFactory.addAdvice(new AfterReturningAdvice() {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target)throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {System.out.printf("[AfterReturningAdvice] 当前存放是 Key: %s , 新存放的 Value : %s , 之前关联的 Value : %s\n ",args[0],    // keyargs[1],    // new valuereturnValue // old value);}}
});// 通过代理对象存储数据
Map<String, Object> proxy = proxyFactory.getProxy();
proxy.put("1", "A");
proxy.put("1", "B");
System.out.println(cache.get("1"));

(4)同一个@Before执行顺序

注解驱动:使用@Order注解标注切面类,同一类中的顺序无法保证。

XML驱动:按照先后顺序执行。

未完待续

参考资料

极客时间《小马哥讲 Spring AOP 编程思想》

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

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

相关文章

如何使用 ChatGPT 编写 SQL JOIN 查询

通过清晰的示例和解释&#xff0c;本文展示了 ChatGPT 如何简化和简化创建复杂 MySQL 查询的过程&#xff0c;使用户更容易与数据库交互并检索他们需要的数据。无论您是初学者还是经验丰富的开发人员&#xff0c;本文都提供了有关如何利用 ChatGPT 来增强您的 MySQL 查询编写技…

微信公众号抽奖怎么做_分享微信抽奖小程序制作的好处

在H5游戏中&#xff0c;抽奖是最受消费者喜爱的模式之一。将H5微信抽奖活动结合到营销中&#xff0c;可以带来意想不到的效果&#xff0c;带流量和曝光率&#xff0c;所以许多企业也会在做活动时添加上不同类型的H5微信抽奖活动。编辑那么&#xff0c;新手怎么搭建微信抽奖活动…

钓鱼网站+persistence植入后门程序+创建用户

本实验实现1&#xff1a; 利用MS14-064漏洞&#xff0c;会生成一个网址&#xff0c;诱导用户点击&#xff0c;打开后&#xff0c;会直接连接到发起攻击的主机上&#xff0c;即可攻击成功。 本实验实现2&#xff1a; 一旦入侵成功&#xff0c;则拿到控制目标主机的部分权限&…

【论文阅读】SSR-Net: 一个小型的 软分段回归网络 用于年龄估计

原始题目SSR-Net: A Compact Soft Stagewise Regression Network for Age Estimation中文名称SSR-Net: 一个小型的 软分段回归网络 用于年龄估计发表时间2018年7月13日平台IJCAI-18来源台湾中央研究院、国立台湾大学文章链接https://www.ijcai.org/proceedings/2018/0150.pdf开…

2023-02-20干活小计:

所以我今天的活开始了&#xff1a; In this paper, the authors target the problem of Multimodal Name Entity Recognition(MNER) as an improvement on NER(text only) The paper proposes a multimodal fusion based on a heterogeneous graph of texts and images to mak…

Renegade:基于MPC+Bulletproofs构建的anonymous DEX

1. 引言 白皮书见&#xff1a; Renegade Whitepaper: Protocol Specification, v0.6 开源代码见&#xff1a; https://github.com/renegade-fi/renegade&#xff08;Renegade p2p网络每个节点的核心网络和密码逻辑&#xff09;https://github.com/renegade-fi/mpc-bulletpr…

OpenShift 4 - 将 VMware 虚机迁移至 OpenShift Virtualization(视频)- 温迁移

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在支持 OpenShift 4.12 的 OpenShift 环境中验证 文章目录了解 Warm Migration为 VMware VM 配置 CBT用 Warm Migration 方式迁移 VMware VM创建 Migration plan执行 Migration plan演示视频了解 Warm Migr…

漫画 | Python是一门烂语言?

这个电脑的主人是个程序员&#xff0c;他相继学习了C、Java、Python、Go&#xff0c; 但是似乎总是停留在Hello World的水平。 每天晚上&#xff0c;夜深人静的时候&#xff0c;这些Hello World程序都会热火朝天地聊天但是&#xff0c;这一天发生了可怕的事情随着各个Hello wor…

小程序(十)签到业务流程分析

文章目录一、如何获取地理信息&#xff1f;二、如何判定某地区新冠疫情的风险等级&#xff1f;系统的人脸签到模块包含的功能非常丰富&#xff0c;不仅仅只有人脸识别的签到功能&#xff0c;而且还可以根据用户签到时候的地理定位&#xff0c;计算出该地区是 新冠疫情 的 高风险…

【可视化实战】Python 绘制出来的数据大屏真的太惊艳了

今天我们在进行一个Python数据可视化的实战练习&#xff0c;用到的模块叫做Panel&#xff0c;我们通过调用此模块来绘制动态可交互的图表以及数据大屏的制作。 而本地需要用到的数据集&#xff0c;可在kaggle上面获取 https://www.kaggle.com/datasets/rtatman/188-million-us…

【STM32笔记】__WFI();进入不了休眠的可能原因(系统定时器SysTick一直产生中断)

【STM32笔记】__WFI()&#xff1b;进入不了休眠的可能原因&#xff08;系统定时器SysTick一直产生中断&#xff09; 【STM32笔记】低功耗模式配置及避坑汇总 前文&#xff1a; blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置&am…

UnsupportedOperationException

原因&#xff1a;返回值为list时&#xff0c;返回值类型应为具体的类型参考文章&#xff1a;(139条消息) mybatis中返回结果类型为集合类型&#xff08;List、Map&#xff09;_毒毒毒毒丶的博客-CSDN博客_mybatis返回list<map>集合UnsupportedOperationException 是用于表…

【算法基础】线性、二分法查找

问题&#xff1a; 现有数组int[] arr new int[]{1,3,5,63,2,55,78}&#xff0c;找出值为2的元素&#xff0c;并返回其下标。 1. 线性查找&#xff08;顺序查找&#xff09; 声明两个变量&#xff1a;查找的元素、保存索引的变量用for循环依次遍历 注意&#xff1a; 这里只查…

TCP的三次握手、四次挥手

文章目录前言一、一些重要字段的含义二、TCP总括图三、三次握手详细过程1.第一次握手2.第二次握手3.第三次握手三次握手小结4.为什么必须要进行三次握手&#xff0c;两次或四次就不行四、四次挥手1.第一次挥手2.第二次挥手3.第三次挥手4.第四次挥手四次挥手简述前言 一个TCP的…

gulimall技术栈笔记

文章目录1.项目背景1.1电商模式1.2谷粒商城2.项目架构图3.项目技术&特色4.项目前置要求5.分布式基础概念5.1微服务5.2集群&分布式&节点5.3远程调用5.4负载均衡5.5服务注册/发现&注册中心5.6配置中心5.7服务熔断&服务降级5.7.1服务熔断5.7.2服务降级5.8API网…

Allegro如何通过报表的方式检查单板上是否有假器件操作指导

Allegro如何通过报表的方式检查单板上是否有假器件操作指导 在做PCB设计的时候,输出生产文件之前,必须保证PCB上不能存在假器件,如下图,是不被允许的 当PCB单板比较大,如何通过报表的方式检查是否存在假器件,具体操作如下 点击Tools点击Reports

【华为云-开发者专属集市】DevCloud+ECS、MySQL搭建WordPress

文章目录AppBazaar官网选择与购买项目项目概况操作过程购买DevCloud服务创建项目添加制品库应用部署购买ECS添加部署模板并执行任务故障排除安装及访问WordPress登录网站管理后台访问网站完善部署模板资源释放使用总结AppBazaar官网 首先&#xff0c;我们来到AppBazaar的官网&…

大数据Hadoop教程-01大数据导论与Linux基础

目录 01、大数据导论 02、Linux操作系统概述 P007 P008 P009 P010 P011 P012 P013 P014 P015 P016 P017 01、大数据导论 企业数据分析方向 现状分析&#xff08;分析当下的数据&#xff09;&#xff1a;现阶段的整体情况&#xff0c;各个部分的构成占比、发展、变…

揭开JavaWeb中Cookie与Session的神秘面纱

文章目录1&#xff0c;会话跟踪技术的概述2&#xff0c;Cookie2.1 Cookie的基本使用2.2 Cookie的原理分析2.3 Cookie的使用细节2.3.1 Cookie的存活时间2.3.2 Cookie存储中文3&#xff0c;Session3.1 Session的基本使用3.2 Session的原理分析3.3 Session的使用细节3.3.1 Session…

通过命令行快速了解电脑CPU架构

Linux 和 MacOS 使用终端&#xff08;小黑窗&#xff09;执行下面的命令&#xff0c;根据输出结果查表&#xff1a; uname -m输出 的内容分别对应架构 输出对应架构i386, i686i386x86_64amd64arm, armelarm_garbagearmv7l, armhfarmv7*mipsmips*mips64mips64*Window 按 WinR …