AspectJ in action

news/2024/4/29 12:56:37/文章来源:https://blog.csdn.net/shaotianyang12/article/details/127264339

Discovering AOP

This chapter covers
■ Understanding crosscutting concerns
■ Modularizing crosscutting concerns using AOP
■ Understanding AOP languages

Reflect back on your last project, and compare it with a project you worked on a few
years back. What’s the difference? One word: complexity. Today’s software systems are
complex, and all indications point to even faster growth in software complexity in
the coming years. What can a software developer do to manage complexity?
If complexity is the problem, modularization is the solution. By breaking the
problem into more manageable pieces, you have a better shot at implementing
each piece. When you’re faced with complex software requirements, you’re likely
to break those into multiple parts such as business functionality, data access, and
presentation logic. We call each of these functionalities concerns of the system. In a
banking system, you may be concerned with customer management, account management, and loan management. You may also have an implementation of data
access and the web layer. We call these core concerns because they form the core
functionality of the system. Other concerns, such as security, logging, resource
pooling, caching, performance monitoring, concurrency control, and transaction
management, cut across—or crosscut—many other modules. We call these functionalities crosscutting concerns.
For core concerns, object-oriented programming (OOP), the dominant methodology employed today, does a good job. You can immediately see a class such as
LoanManagementService implementing business logic and AccountRepository implementing data access. But what about crosscutting concerns? Wouldn’t it be nice if you
could implement a module that you identify as Security, Auditing, or PerformanceMonitor? You can’t do that with OOP alone. Instead, OOP forces you to fuse the implementation of these functionalities in many modules. This is where aspect-oriented
programming (AOP) helps.
AOP is a methodology that provides separation of crosscutting concerns by introducing a new unit of modularization—an aspect. Each aspect focuses on a specific
crosscutting functionality. The core classes are no longer burdened with crosscutting
concerns. An aspect weaver composes the final system by combining the core classes
and crosscutting aspects through a process called weaving. Thus, AOP helps to create
applications that are easier to design, implement, and maintain.
In this chapter, we’ll examine the fundamentals of AOP, the problems it addresses,
and why you need to know about it. In the rest of the book, we’ll examine AspectJ,
which is a specific implementation of AOP. Let’s start by discussing how you manage
various concerns without AOP, which will help you understand why you need AOP.

1.1 Life without AOP

How do you implement crosscutting concerns using OOP alone? Typically, you add the
code needed for each crosscutting concern in each module, as shown in figure 1.1.
This figure shows how different modules in a system implement both core concerns and crosscutting concerns. Let’s illustrate the same idea through a code snippet.
Consider the skeleton implementation of a representative class that encapsulates
some business logic in a conventional way, shown in listing 1.1. A system consists of
many such classes.
在这里插入图片描述
在这里插入图片描述
Although the details will vary, the listing shows a common problem many developers
face: a conceptual separation exists between multiple concerns at design time, but
implementation tangles them together. Such an implementation also breaks the Single
Responsibility Principle (SRP)1
by making the class responsible for implementing core
and crosscutting concerns. If you need to change the invocation of the code related to
crosscutting concerns, you must change each class that includes such an invocation.
Doing so breaks the Open/Close principle2
—open for extension, but closed for modifications. The overall consequence is a higher cost of implementing features and fixing bugs.
With conventional implementations, core and crosscutting concerns are tangled in
each module. Furthermore, each crosscutting concern is scattered in many modules.
The presence of code tangling and code scattering is a tell-tale sign of the conventional implementation of crosscutting concerns.3
Let’s examine them in detail.

1.1.1 Code tangling

Code tangling is caused when a module is implemented to handle multiple concerns
simultaneously. Developers often consider concerns such as business logic, performance, synchronization, logging, security, and so forth when implementing a module.
在这里插入图片描述
This leads to the simultaneous presence of elements from each concern’s implementation and results in code tangling. Figure 1.2 illustrates code tangling in a module.
Another way to look at code tangling is to use the notion of a multidimensional
concern space. Imagine that you’re projecting the application requirements onto a
multidimensional concern space, with each concern forming a dimension. Here, all
the concerns are mutually independent and therefore can evolve without affecting
the rest. For example, changing the security requirement from one kind of authorization scheme to another shouldn’t affect the business logic. But as you see in figure 1.3,
a multidimensional concern space collapses into a one-dimensional implementation space.
Because the implementation space is one-dimensional, its focus is usually the
implementation of the core concern that takes the role of the dominant dimension; other concerns then tangle the core concern. Although you may naturally separate the individual requirements into mutually independent concerns during the
design phase, OOP alone doesn’t let you retain the separation in the implementation phase.
We’ve looked at the first symptom of crosscutting concerns when implemented
using traditional techniques; now, let’s move on to the next.
在这里插入图片描述

1.1.1 Code scattering

Code scattering is caused when a single functionality is implemented in multiple modules. Because crosscutting concerns, by definition, are spread over many modules,
related implementations are also scattered over all those modules. For example, in a
system using a database, performance concerns may affect all the modules accessing
the database.
Figure 1.4 shows how a banking system implements security using conventional
techniques. Even when using a well-designed security module that offers an abstract
API and hides the details, each client—the accounting module, the ATM module, and
the database module—still needs the code to invoke the security API to check permission. The code for checking permission is scattered across multiple modules, and
there is no single place to identify the concern. The overall effect is an undesired tangling between the modules to be secured and the security module.
在这里插入图片描述
Code tangling and code scattering together impact software design and development
in many ways: poor traceability, lower productivity, lower code reuse, poor quality, and
difficult evolution. All of these problems lead us to search for better approaches to
architecture, design, and implementation. Aspect-oriented programming is one viable
solution. In the next section, we’ll introduce you to AOP. Later in this chapter, we’ll
examine alternatives to AOP as well.

1.2 Modularizing with AOP

In OOP, the core concerns can be loosely coupled through interfaces, but there is no
easy way to do the same for crosscutting concerns. This is because a concern is implemented in two parts: the server-side piece and the client-side piece. OOP modularizes
the server part quite well in classes and interfaces. But when the concern is of a crosscutting nature, the client part (consisting of the requests to the server) is spread over
all the clients.

NOTE:We use the terms server and client here in the classic OOP sense to mean the
objects that are providing a certain set of services and the objects using
those services. Don’t confuse them with networking servers and clients.

As an example, let’s take another look at the typical implementation of a crosscutting
concern in OOP, shown in figure 1.4. The security module provides its services
through an interface. The use of an interface loosens the coupling between the clients and the implementations of the interface. Clients that use the security services
through the interface are oblivious to the exact implementation they’re using; any
changes to the implementation don’t require changes to the clients themselves. Likewise, replacing one security implementation with another is just a matter of instantiating the right kind of implementation. The result is that you can replace one security
implementation with another with little or no change to the individual client modules. But this arrangement still requires that each client have the embedded code to
call the API. Such calls must be included in all the modules requiring security and are
tangled with their core logic.
Using AOP, none of the core modules contain calls to the security API. Figure 1.5
shows the AOP implementation of the same security functionality shown in figure 1.4.
The security concern—implementation and invocations—now resides entirely inside
the security module and the security aspect. For now, don’t worry about the way in
which AOP achieves this; we’ll explain in the next section.
The fundamental change that AOP brings is the preservation of the mutual independence of the individual concerns. Implementations can be easily mapped back to
the corresponding concerns, resulting in a system that is simpler to understand, easier
to implement, and more adaptable to changes.
在这里插入图片描述

1.3 Anatomy of an AOP language

The AOP methodology is just that—a methodology. In order to be of any use in the
real world, it must be implemented, or realized. Each realization of AOP involves specifying a language or a framework and associated tools. Like any other programming
methodology, an AOP implementation consists of two parts:
■ The language specification describes the language constructs and syntax to
express implementation of the core and crosscutting concerns.
■ The language implementation verifies the code’s adherence to the language specification and translates the code into an executable form.

1.3.1 The AOP language specification

Any implementation of AOP must specify a language to implement the individual
concerns and a language to implement the weaving rules. Note that an AOP system
may offer a homogeneous language that doesn’t distinguish between the two parts.
This is likely to be the case in future AOP languages. Let’s take a closer look at these
two parts.
IMPLEMENTATION OF CONCERNS
As in other methodologies, the concerns of a system are implemented into modules
that contain the data and behavior needed to provide their services. A module that
implements the core part of the caching concern maintains a collection of cached
objects, manages the validity of the cached objects, and ensures bounded memory
consumption. To implement both the core and crosscutting concerns, we normally
use standard languages such as C, C++, and Java.
WEAVING RULES SPECIFICATION
Weaving rules specify how to combine the implemented concerns in order to form the
final system. After you implement the core part of the caching concern in a module
(perhaps through a third-party class library), you must introduce caching into the system. The weaving rule in this case specifies the data that needs to be cached, the information that forms the key into the cache storage, and so forth. The system then uses
these rules to obtain and update cache from the specified operations.
The power of AOP comes from the economical way of expressing the weaving
rules. For instance, to modularize tracing concerns in listing 1.1, you can add a few
lines of code to specify that all the public operations in the system should be logged.
Here is a weaving specification for the tracing aspect:
■ Rule 1: Create a logger object.
■ Rule 2: Log the beginning of each public operation.
■ Rule 3: Log the completion of each public operation.
This is much more succinct than modifying each public operation to add logging
code. Because the tracing concern is modularized away from the class, it may focus
only on the core concern, as follows:
在这里插入图片描述
Compare this class with the one in listing 1.1: all the code to perform tracing—the
ancillary concerns from the class’s point of view—have been removed. When you
apply the same process to other crosscutting concerns, only the core business logic
remains in the class. As you’ll see in the next section, an AOP implementation combines the classes and aspects to produce a woven executable.
Weaving rules can be general or specific in the ways they interact with the core
modules. In the previous logging example, the weaving rules don’t need to mention
any specific classes or methods in the system. On the other end of the spectrum, a
weaving rule may specify that a business rule should be applied only to specific methods, such as the credit() and debit() operations in the Account class or the ones
that carry the @ReadOnly annotation. The specificity of the weaving rules determines
the level of coupling between the aspect and core logic.
The language used to specify weaving rules can be a natural extension of that language or something entirely different. For example, an AOP implementation using Java
as the base language might introduce new extensions that blend well with the base language, or it could use a separate XML-based language to express weaving rules.

1.3.2 The AOP language implementation

The AOP language implementation performs two logical steps: It first combines the
individual concerns using the weaving rules, and then it converts the resulting information into executable code. AOP implementation thus requires the use of a processor—weaver—to perform these steps.
An AOP system can implement the weaver in various ways. A simple approach uses
source-to-source translation. Here, the weaver processes source code for individual
classes and aspects to produce woven source code. The aspect compiler then feeds
this woven code to the base language compiler to produce the final executable code.
This was the implementation technique used in early implementations of AspectJ.
The approach suffers from several drawbacks because the executable code can’t be
easily traced back to the original source code. For example, stack traces indicate line
numbers in woven source code.
Another approach first compiles the source code using the base language compiler. Then, the resulting files are fed to the aspect compiler, which weaves those files.
Figure 1.6 shows a schematic of a compiler-based AOP language implementation.
An AOP system may also be able to push the weaving process close to execution of
the system. If the implementation of AOP is Java-based, a special class loader or a virtual
在这里插入图片描述
machine (VM) agent can perform the weaving. Such an implementation first loads the
byte code for the aspects, weaves them into the classes as they’re being loaded, and supplies those woven versions of the classes to the underlying VM.
Yet another implementation could use automatically created proxies. In this case,
each object that needs weaving is wrapped inside a proxy. Such an implementation
typically works well in conjunction with another framework that controls the creation
of objects. In this way, the framework can wrap each created object in a proxy.
So far, we’ve looked at the mechanics of an AOP system. Now, let’s examine AOP’s
fundamental concepts.

1.4 Fundamental concepts in AOP

By now, it should be clear that AOP systems help in modularizing crosscutting concerns. But so do many other technologies, such as byte-code manipulation tools,
direct use of the proxy design pattern, and meta-programming. How do you differentiate AOP from these options? To find out, we need to distill the core characteristics of
AOP systems into a generic model. If a system fits that model, it’s an AOP system.
To implement a crosscutting concern, an AOP system may include many of the following concepts:
■ Identifiable points in the execution of the system —The system exposes points during
the execution of the system. These may include execution of methods, creation
of objects, or throwing of exceptions. Such identifiable points in the system are
called join points. Note that join points are present in all systems—even those
that don’t use AOP—because they’re points during execution of a system. AOP
merely identifies and categorizes these points.
■ A construct for selecting join points —Implementing a crosscutting concern
requires selecting a specific set of join points. For example, the tracing aspect
discussed earlier needs to select only the public methods in the system. The
pointcut construct selects any join point that satisfies the criteria. This is similar
to an SQL query selecting rows in database (we’ll compare AOP with databases
in section 1.5.2). A pointcut may use another pointcut to form a complex selection. Pointcuts also collect context at the selected points. For example, a pointcut may collect method arguments as context. The concept of join points and
the pointcut construct together form an AOP system’s join point model. We’ll
study AspectJ’s join point model in chapter 3.
■ A construct to alter program behavior —After a pointcut selects join points, you
must augment those join points with additional or alternative behavior. The
advice construct in AOP provides a facility to do so. An advice adds behavior
before, after, or around the selected join points. Before advice executes before
the join point, whereas after advice executes after it. Around advice surrounds
the join point execution and may execute it zero or more times. Advice is a
form of dynamic crosscutting because it affects the execution of the system. We’ll
study AspectJ’s dynamic crosscutting implementation in chapter 4.
■ Constructs to alter static structure of the system —Sometimes, to implement crosscutting functionality effectively, you must alter the static structure of the system.
For example, when implementing tracing, you may need to introduce the logger field into each traced class; inter-type declaration constructs make such modifications possible. In some situations, you may need to detect certain conditions,
typically the existence of particular join points, before the execution of the system; weave-time declaration constructs allow such possibilities. Collectively, all
these mechanisms are referred to as static crosscutting, given their effect on the
static structure, as opposed to dynamic behavior changes to the execution of
the system. We’ll study AspectJ’s static crosscutting support in chapter 5.
■ A module to express all crosscutting constructs —Because the end goal of AOP is to
have a module that embeds crosscutting logic, you need a place to express that
logic. The aspect construct provides such a place. An aspect contains pointcuts,
advice, and static crosscutting constructs. It may be related to other aspects in a
similar way to how a class relates to other classes. Aspects become a part of the
system and use the system (for example, classes in it) to get their work done.
We’ll examine AspectJ’s implementation of aspect in chapter 6.
Figure 1.7 shows all these players and their relationships to each other in an AOP system.
Each AOP system may implement a subset of the model. For example, Spring AOP
(discussed in chapter 9) doesn’t implement weave-time declarations due to its emphasis on its runtime nature. On the other hand, the join point model is so central to
AOP that every AOP system must support it—everything else revolves around the joinpoint model.
When you encounter a solution that modularizes crosscutting concerns, try to map
it onto the generic AOP model. If you can, then that solution is indeed an AOP system.
Otherwise, it’s an alternative approach for solving the problem of crosscutting concerns.
在这里插入图片描述

1.5 AOP by analogy

When you’re learning a new technology, it sometimes helps to compare it with existing technologies. In this section, we’ll attempt to help you understand AOP by
comparing it with Cascading Style Sheets (CSS), database programming, and eventoriented systems. The purpose of this section is to help those familiar with at least one
of these technologies to understand AOP by analogy.

1.5.1 Cascading Style Sheets (CSS)

CSS is a widely supported mechanism to separate content from presentation in HTML
pages. Without CSS, formatting information is fused with content (causing tangling),
and similar content elements have presentational information spread into multiple
places (causing scattering). CSS helps the situation by letting the main document focus
on content by separating the formatting information into a document called a stylesheet.
A core concept in CSS is a selector that selects document elements matching a certain specification. For example, the body p selector can select paragraphs inside the
body element. You can then associate presentational information with a selector and,
for example, set the background color of such elements to blue using the body p
{background: blue;} element.
AOP acts on classes in the same way that CSS acts on documents. AOP lets you separate crosscutting logic from the main-line logic. AOP’s pointcuts have the same selection role as CSS selectors. Whereas CSS selectors select structural elements in a
document, pointcuts select program elements. Similarly, the blocks describing the formatting information are analogous to AOP advice in functionality.
Often, the selection mechanism requires more information than merely using the
inherent characteristics of a structure such as body p. It’s common practice to supplement content elements with additional metadata through the class attribute. For
example, you can mark an HTML paragraph element as menu by using the tag

1.5.2 Database systems

Database systems offer “dynamic crosscutting” targeted toward data access, whereas
AOP offers a similar mechanism toward general programming. It offers two good analogies to AOP concepts: SQL with pointcuts and triggers with advice.
SQL AND POINTCUTS
A join point is like a row in a database, whereas a pointcut is like an SQL query. An SQL
query selects rows according to a specified criterion such as “rows in accounts table,
where the balance is greater than 50”. It provides access to the content of the selected
rows. Similarly, a pointcut is a query over program execution that selects join points
according to a specified criterion such as “method execution in the Account class,
where the method name starts with ‘set’”. It also provides access to the join point context (objects available at the join point, such as method arguments).
TRIGGERS AND ADVICE
Database programming often uses triggers to respond to changes made in data. For
example, you can use a trigger to audit changes in certain tables. The following snippet calls the logInventoryIncrease() procedure when inventory increases:
在这里插入图片描述
The static condition, such as the name of the table and the modified column, as well
as the dynamic condition, such as the difference in the column value, are analogous
to AOP’s pointcut concept. Both describe a selection criterion to “trigger” certain
actions. The stored procedure specified in the trigger is analogous to AOP’s advice.
Database triggers and AOP’s advice both modify the normal program execution to
carry additional or alternative actions. But there are some obvious differences. Database triggers are useful only for database operations. AOP has a more general
approach that can be used for many other purposes. But note that AOP doesn’t necessarily obviate the need for database triggers, for reasons such as performance and
bringing uniformity to multiple applications accessing the same tables.
Similar to database triggers, event-oriented programming includes the notion of
responding to events.

1.5.3 Event-oriented programming

Event-oriented programming is essentially the observer design pattern (we’ll discuss it
as an alternative to AOP in section 1.7.3). Each interested code site notifies the observers by firing events, and the observers respond by taking appropriate action, which
may be crosscutting in nature.
In AOP, the program is woven with logic to fire virtual events and to respond to the
events with an action that corresponds to the crosscutting concern it’s implementing.
But note this important difference: Unlike in event-based programming, there is no
explicit code for the creation and firing of events in the subject classes. Executing part
of the program constitutes the virtual-event generation. Also, event systems tend to be
more coarse-grained than an AOP solution implements.
Note that you can effectively combine event-oriented programming with AOP. Essentially, you can modularize the crosscutting concern of firing events into an aspect. With
such an implementation, you avoid tangling the core code with the event-firing logic.
Now that you have a good understanding of AOP, let’s turn our attention to a bit of
history and the current status of AOP implementations.

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

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

相关文章

一文带你快速鉴别CookieSession

文章目录会话跟踪技术1、相关基础概念2、Cookie2.1 Cookie的基本使用2.1.1 发送Cookie2.1.2 获取Cookie2.2 Cookie原理2.3 Cookie存活时间2.4 Cookie存储中文3、Session3.1 Session的基本使用3.2 Session原理3.3 Session的钝化和活化3.4 Session的存活时间总结会话跟踪技术 1、…

SSl证书协议作用

SSl证书协议作用 随着移动互联网时代的飞速发展,似乎每周都能看到很多关于数据泄露的新闻,而且报道还在不断涌现。在统计的100款app中,有多达91款app收集了过多的用户个人信息。 为了改善这一现象,网络空间管理局联合发布了《认定…

TRC丨艾美捷TRC 2-氨基-2-甲基丙酰胺说明书

艾美捷TRC 2-氨基-2-甲基丙酰胺化学性质: 目录号A010210 化学名称2-氨基-2-甲基丙酰胺 CAS 编号16252-90-7 分子式C₄H₁₀N2O 外貌白色固体 熔点>250C(分解) 分子量102.14 溶解度甲醇(少量) 类别建筑模块…

听说2022金九银十变成铜九铁十了......

往年的金九银十,今年被戏称为“铜九铁十”。知名的大厂HR们都在不断的裁员,能被保住不被裁掉可能就万事大吉了,赛道越来越窄,都在预测未来计算机行业是不是下一个土木工程? 我也算是软件测试岗位的老鸟了,…

计算机网络03之可靠传输

1. 停止等待协议 1.概述 发送方每次只能发送一个数据包,确认方每次只能发送一个确认。发送方收到重复的确认会丢弃(接收方已经接收),接收方收到重复的数据,会把数据丢弃,但是会发送确认(防止上…

DETR:End-to-End Object Detection with Transformers

论文地址:https://arxiv.org/abs/2005.12872 代码地址:https://github.com/facebookresearch/detr 在看完Transformer之后,将会开始看视觉类的Transformer应用。本篇论文出自ECCV20,是关于目标检测的论文。DETR,即Det…

pyinstaller打包多个python程序

以下两个python文件 get_file_message_main.py为执行文件,继承了get_file_message.py中的类 打开终端cmd 切换到桌面 cd desktop切换到指定路径 cd python打包pyi-makespec pyi-makespec get_file_message_main.py生成get_file_message_main.spec文件 .spec文…

信息增益计算和决策树生长过程

信息增益计算和决策树生长过程 给定训练集S,下面以信息增益作为最佳划分的标准,演示信息增益的计算和决策树生长的过程: 根节点 (1)以“Outlook”被选做划分属性 总共有14条数据,打球9条,不打…

[Windows内核源码分析5] 引导过程(对象管理器初始化在Phase1部分的分析)

在第1阶段, ObInitSystem首先对每个处理器的PRCB结构的lookaside链表进行初始化。 在全局名字空间中创建根目录\ 来看一下NtCreateDirectoryObject这个函数实际上是ObCreateObject和ObInsertDirectory的封装。其内部执行的操作很简单,一个是创建一个目录对象, 接着…

y160.第九章 GitOps从入门到精通 -- Tekton Trigger(九)

8.Tekton Trigger 8.1 Tekton Trigger 基础 Tekton Triggers简介 监控特定的事件,并在满足条件时自动触发Tekton Pipeline; 例如,代码仓库上的创建pull request、push代码,以及合并pull request至main分支等Tekton Triggers为用户提供了一种声明式API 它允许用户按需定义监…

客户管理系统(SSM版):解除线索关联市场活动

一、客户需求: 用户在线索明细页面,点击某一个"解除关联"按钮,弹出确认解除的窗口; 用户点击"确定"按钮,完成解除线索关联市场活动的功能. *解除成功之后,刷新已经关联的市场活动列表 *解除失败,提示信息,列表也不刷新 二、功能实现 1.首…

openjdk源码准备编译和依赖

在Windows系统上进行openjdk的源码编译 一、准备编译需要的装备 1.首先下载一个软件Cygwin。这个软件是一个在Windows平台下模拟Linux运行环境的软件,提供了一系列的Linux的运行命令。(解释这些,有兴趣的自己百度) 下载的路径点…

Web APIs:事件基础

事件三要素 1.事件是有三部分组成 事件源 事件类型 事件处理程序 (1)事件源 事件被触发的对象 谁 按钮 (2)事件类型 如何触发 什么事件 比如鼠标点击(click),经过 还是键盘按下 &…

TRC丨艾美捷TRC D-Abequose说明书

艾美捷TRC D-Abequose是一种甜味剂和增味剂配方,适用于食品、饮料、药物和化妆品用途。 艾美捷TRC D-Abequose化学性质: 目录号A010205 化学名称D-Abequose CAS 编号56816-60-5 分子式C₆H₁₂O₄ 分子量148.16 贮存4C 溶解度甲醇(少许…

【蓝桥杯国赛】H 机房

蓝桥杯2022年第十三届决赛真题-机房 - C语言网 (dotcpp.com) 题意: 一共有n个结点,n-1条边,因此这是棵树 信息经过一个结点,就会产生一定的延迟,具体延迟的时间等于该结点的度数 每次询问树上两个结点,问…

c++学习

C学习Static变量生存期和作用域静态局部变量类的继承多态虚函数纯虚函数(接口)可见性数组字符串constmutable成员初始化列表三元操作符在堆、栈上创建C实例化对象C运算符和其重载thisC对象的生存期智能指针uniqueptr(作用域指针)s…

Ubuntu安装微信

1.安装wine sudo dpkg --add-architecture i386 sudo mkdir -pm755 /etc/apt/keyrings sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key//根据你的系统执行不同的命令 Ubuntu 22.04 sudo wget -NP /etc/apt/sources.list.d/…

快乐刷课---Tampermonkey下载使用

TampermonkeyChrome插件伴侣下载资源: 链接:https://pan.baidu.com/s/1IIzB8N2iPW2RjUO2pqDVHw?pwd6666 提取码:6666 1. 下载 Tampermonkey 进入油猴的官网Tampermonkey,下载你使用的浏览器对应的版本 以谷歌浏览器为例&am…

如何计算维吉尼亚密码?Java实现维吉尼亚密码的加密解密算法

文章目录如何计算维吉尼亚密码?Java实现加密算法Java实现解密算法参考博客如何计算维吉尼亚密码? 计算维吉尼亚密码有2种方式,一种是根据密码表查找,另一种是手动计算方法。 1.密码表查找法 第一行是密钥,第一列是明文…

CH579 Cortex-M0 内核低功耗蓝牙 MCU 集成 ARM 内核 32 位微控制器

概述 CH579 是集成 BLE 无线通讯的 ARM 内核 32 位微控制器。片上集成低功耗蓝牙 BLE 通讯模块、以太网控制器及收发器、全速 USB 主机和设备控制器及收发器、段式 LCD 驱动模块、ADC、触摸按键检测模块、RTC 等丰富的外设资源。 特点 32 位 ARM Cortex-M0 内核,…