当前位置: 首页 > news >正文

C#高级篇 反射和属性详解【代码之美系列】

🎀🎀🎀代码之美系列目录🎀🎀🎀

一、C# 命名规则规范
二、C# 代码约定规范
三、C# 参数类型约束
四、浅析 B/S 应用程序体系结构原则
五、浅析 C# Async 和 Await
六、浅析 ASP.NET Core SignalR 双工通信
七、浅析 ASP.NET Core 和 MongoDB 创建 Web API
八、浅析 ASP.NET Web UI 框架 Razor Pages/MVC/Web API/Blazor
九、如何使用 MiniProfiler WebAPI 分析工具
十、浅析 .NET Core 中各种 Filter
十一、C#.Net筑基-类型系统
十二、C#.Net 筑基-运算符
十三、C#.Net筑基-解密委托与事件
十四、C#.Net筑基-集合知识大全
十五、C#.Net筑基 - 常见类型
十六、C#.NET体系图文概述—2024最全总结
十七、C# 强大无匹的模式匹配,让代码更加优雅
十八、C# 中的记录类型简介
十九、C# 异步编程模型【代码之美系列】
二十、C#高级篇 反射和属性详解【代码之美系列】


在这里插入图片描述


文章目录

  • 🎀🎀🎀代码之美系列目录🎀🎀🎀
  • 一、属性
    • 1.1 使用属性
    • 1.2 属性参数
    • 1.3 属性目标
    • 1.4 属性的常见用途
    • 1.5 反射概述
  • 二、创建自定义特性
  • 三、使用反射访问特性
  • 四、如何使用特性 (C#) 创建 C/C++ 联合
  • 五、泛型和特性
  • 六、如何使用反射查询程序集的元数据 (LINQ)
  • 七、泛型和反射


一、属性

特性 提供了一种将 元数据声明性 信息与代码(程序集、类型、方法、属性等)相关联的强大方法。将属性与程序实体关联后,可以在 运行时 使用称为反射的技术查询该属性。

属性具有以下属性:

  • 属性将元数据添加到程序中。元数据是有关程序中定义的类型的信息。所有 .NET 程序集都包含一组指定的元数据,用于描述程序集中定义的类型和类型成员。您可以添加自定义属性以指定所需的任何其他信息。
  • 您可以将一个或多个属性应用于整个程序集、模块或较小的程序元素,例如类和属性。
  • Attributes 可以像 methodsproperties 一样接受参数。
  • 您的程序可以使用反射检查自己的元数据或其他程序中的元数据。

反射 提供描述程序集、模块和类型的对象(类型 Type)。您可以使用反射动态创建类型的实例,将类型绑定到现有对象,或者从现有对象获取类型并调用其方法或访问其字段和属性。如果您在代码中使用属性,则反射使您能够访问它们。

下面是一个使用 GetType() 方法(由基类中的所有类型继承)获取变量类型的反射的简单示例:Object

确保在 .cs 文件的顶部添加 and 。using System;using System.Reflection;

// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

输出为: .System.Int32

下面的示例使用反射来获取加载的程序集的全名。

// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

C# 关键字 和 在中间语言 (IL) 中没有意义,也不用于反射 API。IL 中的相应术语是 Family 和 Assembly。若要使用反射标识方法,请使用 IsAssembly 属性。若要标识方法,请使用 IsFamilyOrAssembly。protectedinternalinternalprotected internal

1.1 使用属性

属性几乎可以放置在任何声明上,尽管特定属性可能会限制它有效的声明类型。在 C# 中,可以通过将用方括号 () 括起来的特性名称放在应用该特性的实体的声明上方来指定特性。[]

在此示例中,SerializableAttribute 属性用于将特定特征应用于类:

[Serializable]
public class SampleClass
{// Objects of this type can be serialized.
}

具有 DllImportAttribute 属性的方法的声明类似于以下示例:

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

可以在声明上放置多个属性,如下例所示:

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

可以为给定实体多次指定某些属性。此类 multiuse 属性的一个示例是 ConditionalAttribute

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{// ...
}

按照约定,所有 属性名称 都以单词 “Attribute” 结尾,以便将它们与 .NET 库中的其他项区分开来。但是,在代码中使用属性时,无需指定属性后缀。例如,等效于 ,但 是 .NET 类库中属性的实际名称。[DllImport][DllImportAttribute]DllImportAttribute

1.2 属性参数

许多属性都有参数,这些参数可以是 positional、unnamed 或 named。任何位置参数都必须按特定顺序指定,并且不能省略。命名参数是可选的,可以按任意顺序指定。首先指定位置参数。例如,这三个属性是等效的:

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

第一个参数(DLL 名称)是位置参数,始终排在最前面;其他的都被命名了。在这种情况下,两个命名参数都默认为 false,因此可以省略它们。位置参数对应于属性构造函数的参数。命名参数或可选参数对应于属性的属性或字段。有关默认参数值的信息,请参阅单个属性的文档。

有关允许的参数类型的更多信息,请参见 C# 语言规范的 Attributes 部分

1.3 属性目标

属性的目标是属性应用到的实体。例如,特性可能应用于类、特定方法或整个程序集。默认情况下,属性适用于其后面的元素。但是,您也可以显式标识,例如,属性是应用于方法、参数还是返回值。

要显式标识属性目标,请使用以下语法:

[target : attribute-list]

下表显示了可能的值列表。target

在这里插入图片描述
您可以指定目标值,以将属性应用于为自动实现的属性创建的支持字段。field

下面的示例演示如何将属性应用于程序集和模块。有关更多信息,请参见 通用属性 (C#)。

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

下面的示例演示如何在 C# 中将属性应用于方法、方法参数和方法返回值。

// default: applies to method
[ValidatedContract]
int Method1() { return 0; }// applies to method
[method: ValidatedContract]
int Method2() { return 0; }// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

无论定义有效的目标是什么,都必须指定目标,即使目标定义为仅应用于返回值也是如此。换句话说,编译器不会使用信息来解决不明确的属性目标。有关更多信息,请参阅 AttributeUsageValidatedContractreturnValidatedContractAttributeUsage

1.4 属性的常见用途

以下列表包括代码中 attribute 的一些常见用法:

  • 在 Web 服务中使用该属性标记方法,以指示该方法应可通过 SOAP 协议调用。有关更多信息,请参阅 WebMethodAttribute。WebMethod
  • 描述在与本机代码互操作时如何封送方法参数。有关详细信息,请参阅 MarshalAsAttribute
  • 描述类、方法和接口的 COM 属性。
  • 使用 DllImportAttribute 类调用非托管代码。
  • 根据标题、版本、描述或商标来描述程序集。
  • 描述要序列化的类的哪些成员以实现持久性。
  • 描述如何在类成员和 XML 节点之间进行映射以进行 XML 序列化。
  • 描述方法的安全要求。
  • 指定用于强制实施安全性的特征。
  • 通过即时 (JIT) 编译器控制优化,使代码易于调试。
  • 获取有关方法的调用方的信息。

1.5 反射概述

反射 在以下情况下非常有用:

  • 当您必须访问程序元数据中的属性时。有关更多信息,请参阅检索存储在属性中的信息。
  • 用于检查和实例化程序集中的类型。
  • 用于在运行时构建新类型。使用 System.Reflection.Emit 中的类。
  • 为了执行后期绑定,访问在运行时创建的类型的方法。请参阅动态加载和使用类型一文。

二、创建自定义特性

可通过定义特性类创建自己的自定义特性,特性类是直接或间接派生自 Attribute 的类,可快速轻松地识别元数据中的特性定义。 假设希望使用编写类型的程序员的姓名来标记该类型。 可能需要定义一个自定义 Author 特性类:

[System.AttributeUsage(System.AttributeTargets.Class |System.AttributeTargets.Struct)
]
public class AuthorAttribute : System.Attribute
{private string Name;public double Version;public AuthorAttribute(string name){Name = name;Version = 1.0;}
}

类名 AuthorAttribute 是该特性的名称,即 Author 加上 Attribute 后缀。 由于该类派生自 System.Attribute,因此它是一个自定义特性类。 构造函数的参数是自定义特性的位置参数。 在此示例中,name 是位置参数。 所有公共读写字段或属性都是命名参数。 在本例中,version 是唯一的命名参数。 请注意,使用 AttributeUsage 特性可使 Author 特性仅对类和 struct 声明有效。

可按如下方式使用这一新特性:

[Author("P. Ackerman", Version = 1.1)]
class SampleClass
{// P. Ackerman's code goes here...
}

AttributeUsage 有一个命名参数 AllowMultiple,通过此命名参数可一次或多次使用自定义特性。 下面的代码示例创建了一个多用特性。

[System.AttributeUsage(System.AttributeTargets.Class |System.AttributeTargets.Struct,AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{string Name;public double Version;public AuthorAttribute(string name){Name = name;// Default value.Version = 1.0;}public string GetName() => Name;
}

在下面的代码示例中,某个类应用了同一类型的多个特性。

[Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
public class ThirdClass
{// ...
}

三、使用反射访问特性

你可以定义自定义特性并将其放入源代码中这一事实,在没有检索该信息并对其进行操作的方法的情况下将没有任何价值。 通过使用反射,可以检索通过自定义特性定义的信息。 主要方法是 GetCustomAttributes,它返回对象数组,这些对象在运行时等效于源代码特性。 此方法有许多重载版本。 有关详细信息,请参阅 Attribute

特性规范,例如:

[Author("P. Ackerman", Version = 1.1)]
class SampleClass { }

在概念上等效于以下代码:

var anonymousAuthorObject = new Author("P. Ackerman")
{Version = 1.1
};

但是,在为特性查询 SampleClass 之前,代码将不会执行。 对 SampleClass 调用 GetCustomAttributes 会导致构造并初始化一个 Author 对象。 如果该类具有其他特性,则将以类似方式构造其他特性对象。 然后 GetCustomAttributes 会以数组形式返回 Author 对象和任何其他特性对象。 之后你便可以循环访问此数组,根据每个数组元素的类型确定所应用的特性,并从特性对象中提取信息。

下面是完整的示例。 定义自定义特性、将其应用于多个实体,并通过反射对其进行检索。

// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |System.AttributeTargets.Struct,AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{string Name;public double Version;public AuthorAttribute(string name){Name = name;// Default value.Version = 1.0;}public string GetName() => Name;
}// Class with the Author attribute.
[Author("P. Ackerman")]
public class FirstClass
{// ...
}// Class without the Author attribute.
public class SecondClass
{// ...
}// Class with multiple Author attributes.
[Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
public class ThirdClass
{// ...
}class TestAuthorAttribute
{public static void Test(){PrintAuthorInfo(typeof(FirstClass));PrintAuthorInfo(typeof(SecondClass));PrintAuthorInfo(typeof(ThirdClass));}private static void PrintAuthorInfo(System.Type t){System.Console.WriteLine($"Author information for {t}");// Using reflection.System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // Reflection.// Displaying output.foreach (System.Attribute attr in attrs){if (attr is AuthorAttribute a){System.Console.WriteLine($"   {a.GetName()}, version {a.Version:f}");}}}
}
/* Output:Author information for FirstClassP. Ackerman, version 1.00Author information for SecondClassAuthor information for ThirdClassR. Koch, version 2.00P. Ackerman, version 1.00
*/

四、如何使用特性 (C#) 创建 C/C++ 联合

通过使用特性,可自定义结构在内存中的布局方式。 例如,可使用 StructLayout(LayoutKind.Explicit) 和 FieldOffset 特性在 C/C++ 中创建所谓的联合。

在此代码段中,TestUnion 的所有字段均从内存中的同一位置开始。

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestUnion
{[System.Runtime.InteropServices.FieldOffset(0)]public int i;[System.Runtime.InteropServices.FieldOffset(0)]public double d;[System.Runtime.InteropServices.FieldOffset(0)]public char c;[System.Runtime.InteropServices.FieldOffset(0)]public byte b;
}

以下代码是另一个示例,其中的字段从不同的显式设置位置开始。

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestExplicit
{[System.Runtime.InteropServices.FieldOffset(0)]public long lg;[System.Runtime.InteropServices.FieldOffset(0)]public int i1;[System.Runtime.InteropServices.FieldOffset(4)]public int i2;[System.Runtime.InteropServices.FieldOffset(8)]public double d;[System.Runtime.InteropServices.FieldOffset(12)]public char c;[System.Runtime.InteropServices.FieldOffset(14)]public byte b;
}

组合的两个整数字段 i1i2lg 共享相同的内存位置。 lg 使用前 8 个字节,或 i1 使用前 4 个字节且 i2 使用后 4 个字节。 使用平台调用时,这种对结构布局的控制很有用。

五、泛型和特性

特性可按与非泛型类型相同的方式应用到泛型类型。 但是,只能将特性应用于开放式泛型类型和封闭式构造泛型类型,而不能应用于部分构造泛型类型。 开放式泛型类型是未指定任何类型参数的类型,例如 Dictionary<TKey, TValue>;封闭式构造泛型类型指定所有类型参数,例如 Dictionary<string, object>。 部分构造泛型类型指定一些(而非全部)类型参数。 示例为 Dictionary<string, TValue>。 未绑定泛型类型是省略类型参数的泛型类型,例如Dictionary<,>。

以下示例使用此自定义属性:

class CustomAttribute : Attribute
{public object? info;
}

属性可以引用未绑定的泛型类型:

public class GenericClass1<T> { }[CustomAttribute(info = typeof(GenericClass1<>))]
class ClassA { }

通过使用适当数量的逗号指定多个类型参数。 在此示例中,GenericClass2 具有两个类型参数:

public class GenericClass2<T, U> { }[CustomAttribute(info = typeof(GenericClass2<,>))]
class ClassB { }

属性可引用封闭式构造泛型类型:

public class GenericClass3<T, U, V> { }[CustomAttribute(info = typeof(GenericClass3<int, double, string>))]
class ClassC { }

引用泛型类型参数的特性导致一个编译时错误:

[CustomAttribute(info = typeof(GenericClass3<int, T, string>))]  //Error CS0416
class ClassD<T> { }

从 C# 11 开始,泛型类型可以从 Attribute 继承:

public class CustomGenericAttribute<T> : Attribute { }  //Requires C# 11

若要在运行时获取有关泛型类型或类型参数的信息,可使用 System.Reflection 方法。 有关详细信息,请参阅泛型和反射。

六、如何使用反射查询程序集的元数据 (LINQ)

使用 .NET 反射 API 检查 .NET 程序集中的元数据,并创建位于该程序集中的类型、类型成员和参数的集合。 因为这些集合支持泛型 IEnumerable<T> 接口,所以可以使用 LINQ 查询它们。

下面的示例演示了如何将 LINQ 与反射配合使用以检索有关与指定搜索条件匹配的方法的特定元数据。 在这种情况下,该查询在返回数组等可枚举类型的程序集中查找所有方法的名称。

Assembly assembly = Assembly.Load("System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");
var pubTypesQuery = from type in assembly.GetTypes()where type.IsPublicfrom method in type.GetMethods()where method.ReturnType.IsArray == true|| (method.ReturnType.GetInterface(typeof(System.Collections.Generic.IEnumerable<>).FullName!) != null&& method.ReturnType.FullName != "System.String")group method.ToString() by type.ToString();foreach (var groupOfMethods in pubTypesQuery)
{Console.WriteLine("Type: {0}", groupOfMethods.Key);foreach (var method in groupOfMethods){Console.WriteLine("  {0}", method);}
}

该示例使用 Assembly.GetTypes 方法返回指定程序集中的类型的数组。 将应用 where 筛选器,以便仅返回公共类型。 对于每个公共类型,子查询使用从 Type.GetMethods 调用返回的 MethodInfo 数组生成。 筛选这些结果,以仅返回其返回类型为数组或实现 IEnumerable<T> 的其他类型的方法。 最后,通过使用类型名称作为键来对这些结果进行分组。

七、泛型和反射

因为公共语言运行时 (CLR) 能够在运行时访问泛型类型信息,所以可以使用反射获取关于泛型类型的信息,方法与用于非泛型类型的方法相同。 有关详细信息,请参阅运行时中的泛型。

System.Reflection.Emit 命名空间还包含支持泛型的新成员。 请参阅如何:使用反射发出定义泛型类型。

有关泛型反射中使用的术语的固定条件列表,请参阅 IsGenericType 属性注解:

  • IsGenericType:如果类型是泛型,则返回 true
  • GetGenericArguments:返回 Type 对象的数组,这些对象表示为构造类型提供的类型实参或泛型类型定义的类型形参。
  • GetGenericTypeDefinition:返回当前构造类型的基础泛型类型定义。
  • GetGenericParameterConstraints:返回表示当前泛型类型参数约束的 Type 对象的数组。
  • ContainsGenericParameters:如果类型或任何其封闭类型或方法包含未提供特定类型的类型参数,则返回 true。
  • GenericParameterAttributes:获取描述当前泛型类型参数的特殊约束的 * GenericParameterAttributes 标志组合。
  • GenericParameterPosition:对于表示类型参数的 Type 对象,获取类型参数在声明其类型参数的泛型类型定义或泛型方法定义的类型参数列表中的位置。
  • IsGenericParameter:获取一个值,该值指示当前 Type 是否表示泛型类型或方法定义中的类型参数。
  • IsGenericTypeDefinition:获取一个值,该值指示当前 Type 是否表示可以用来构造其他泛型类型的泛型类型定义。 如果该类型表示泛型类型的定义,则返回 true
  • DeclaringMethod:返回定义当前泛型类型参数的泛型方法,如果类型参数未由泛型方法定义,则返回 null
  • MakeGenericType:替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 Type 对象。

此外,MethodInfo 类的成员还为泛型方法启用运行时信息。 有关用于反射泛型方法的术语的固定条件列表,请参阅 IsGenericMethod 属性注解:

  • IsGenericMethod:如果方法是泛型,则返回 true。
  • GetGenericArguments:返回类型对象的数组,这些对象表示构造泛型方法的类型实参或泛型方法定义的类型形参。
  • GetGenericMethodDefinition:返回当前构造方法的基础泛型方法定义。
  • ContainsGenericParameters:如果方法或任何其封闭类型包含未提供特定类型的任何类型参数,则返回 true。
  • IsGenericMethodDefinition:如果当前 MethodInfo 表示泛型方法的定义,则返回 true
  • MakeGenericMethod:用类型数组的元素替代当前泛型方法定义的类型参数,并返回表示结果构造方法的 MethodInfo 对象。

在这里插入图片描述

相关文章:

C#高级篇 反射和属性详解【代码之美系列】

&#x1f380;&#x1f380;&#x1f380;代码之美系列目录&#x1f380;&#x1f380;&#x1f380; 一、C# 命名规则规范 二、C# 代码约定规范 三、C# 参数类型约束 四、浅析 B/S 应用程序体系结构原则 五、浅析 C# Async 和 Await 六、浅析 ASP.NET Core SignalR 双工通信 …...

算法 class 005 (对数器C语言实现)

对数器的概念&#xff1a; 用来测试你的算法是否正确。 怎么做呢&#xff1f; 1&#xff1a;比如&#xff0c;写个冒泡排序&#xff0c;作为对比的对象 2&#xff1a;生成一个随机数 数组&#xff0c;用来测试 3&#xff1a;用冒泡排序和你想要验证的那个排序算法&#xff0c;同…...

windows系统安装完Anaconda之后怎么激活自己的虚拟环境并打开jupyter

1.在win主菜单中找到Anaconda安装文件夹并打开终端 文件夹内有所有安装后的Anaconda的应用软件和终端窗口启动窗口 点击Anaconda Prompt&#xff08;Anaconda&#xff09;就会打开类似cmd的命令终端窗口&#xff0c;默认打开的路径是用户名下的路径 2.激活虚拟环境 使用命令…...

leetcode 面试经典 150 题:矩阵置零

链接矩阵置零题序号73题型二维数组解题方法标记数组法难度中等熟练度✅✅✅✅ 题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1]…...

SQL中的TRIM用法

TRIM 是 SQL 中用于去除字符串两端&#xff08;左侧和右侧&#xff09;的空格或特定字符的函数。这个函数常用于清理数据中的无效空白字符&#xff0c;尤其是在从外部系统导入数据时&#xff0c;常常会遇到数据两端有不必要的空格&#xff0c;使用 TRIM 可以去除这些多余的字符…...

Git Flow 工作流:保障修改不破坏主功能的完整指南20241230

Git Flow 工作流&#xff1a;保障修改不破坏主功能的完整指南 引言 在团队协作和个人项目中&#xff0c;Git Flow 是一种可靠的分支管理策略。通过清晰的分工和规范的流程&#xff0c;它能有效保障代码改动的安全性&#xff0c;避免修改破坏主功能&#xff0c;同时提高开发效…...

CentOS 7安装Docker详细教程

本文以 CentOS7.8 为例安装 Docker 26.1.4 、Docker Compose、以及 Docker 镜像仓库。 1.安装Docker社区版 1.1 安装准备 1.1.1 检查系统环境 Docker 不支持32位的 CentOS 7 系统&#xff0c;要求系统内核版本为3.10 以上&#xff0c;可以通过命令 uname -r 来查看当前系统…...

如何在 Ubuntu 22.04 上安装 Varnish HTTP 教程

简介 在本教程中&#xff0c;我们将学习如何在 Ubuntu 22.04 服务器上安装和配置 Varnish HTTP。 Varnish 是一款高性能的 HTTP 加速器&#xff0c;旨在提高内容密集型动态网站的速度。它通过将网页缓存在内存中来工作&#xff0c;从而减少 Web 服务器的负载&#xff0c;并显…...

网络安全概念详解

人们对网络安全工程师的有哪些误会&#xff1f; “你们搞安全的盗个微信号/ QQ号应该很简单吧&#xff1f;” 说起来&#xff0c;我们经常说安全、安全&#xff0c;网络安全到底是什么&#xff1f; 一、什么是网络安全&#xff1f; “网络安全是指网络系统的硬件、软件及其…...

【前端】-音乐播放器(源代码和结构讲解,大家可以将自己喜欢的歌曲添加到数据当中,js实现页面动态显示音乐)

前言&#xff1a;音乐播放器是前端开发中的一个经典项目&#xff0c;通过它可以掌握很多核心技术&#xff0c;如音频处理、DOM操作、事件监听、动画效果等。这个项目不仅能提升前端开发的技能&#xff0c;还能让开发者深入理解JavaScript与HTML的协同作用。 页面展示&#xff1…...

PawSQL性能巡检平台 (3) - 慢查询采集和优化

在数据库运维管理中&#xff0c;慢查询一直是影响系统性能的重要因素。本文将详细介绍PawSQL数据库性能巡检平台在慢查询管理和优化方面的功能特性&#xff0c;帮助数据库管理员更好地应对性能挑战。 一、PawSQL巡检平台慢查询管理概述 PawSQL平台提供了全面的慢查询管理功能&…...

在docker中对MySQL快速部署与初始数据

1.准备工作 将已经准备好的Dockerfile文件与数据库初始化脚本init.sql放到 /usr/local目录中。 Dockerfile文件内容&#xff1a; FROM mysql:5.7 WORKDIR /docker-entrypoint-initdb.d ADD init.sql . FROM 代表来自mysql5.7的镜像&#xff0c;作为基准镜像。 WORKDIR设置工…...

Mysql(MGR)和ProxySQL搭建部署-Kubernetes版本

一、Mysql(MGR) 1.1 statefulSet.yaml apiVersion: apps/v1 kind: StatefulSet metadata:labels:app: mysqlname: mysqlnamespace: yihuazt spec:replicas: 3serviceName: mysql-headlessselector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:affinity:p…...

将现有Web 网页封装为macOS应用

文章目录 方式一&#xff1a;Unite for macOS方式二&#xff1a;Web2Desk方式三&#xff1a;Nativefier方式四&#xff1a;Flutter Flutter WebView Plugin总结 方式一&#xff1a;Unite for macOS Unite 是一款专为 macOS 设计的工具&#xff0c;可以将任意 Web 页面快速封装…...

药片(药丸)和胶囊识别数据集,使用yolo,pasical voc xml, coco json格式标注,可识别药片和胶囊两种标签,2445张原始图片

药片(药丸)和胶囊识别数据集&#xff0c;使用yolo&#xff0c;pasical voc xml, coco json格式标注&#xff0c;可识别药片和胶囊两种标签&#xff0c;2445张原始图片 数据集分割 训练组80&#xff05; 1967图片 有效集13% 317图片 测试集7% 161图片 预处…...

在Linux的世界中怎么玩转定时器任务

定时器使用 先是看到一段使用Linux Sevice服务的脚本&#xff0c;意外发现在ExecStart启动脚本中&#xff0c;它利用无限循环做定时任务的事情&#xff0c;非常突兀&#xff01; 觉得既然用得了Linux Service&#xff0c;那么&#xff0c;与之配套的cron定时器服务是否更应该…...

HTML——20 自定义属性

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>自定义属性</title></head><body><a href"https://ai.m.taobao.com" 自定义属性"属性值">淘宝网</a><a href"h…...

2025:OpenAI的“七十二变”?

朋友们&#xff0c;准备好迎接AI的狂欢了吗&#xff1f;&#x1f680; 是不是跟我一样&#xff0c;每天醒来的第一件事就是看看AI领域又有什么新动向&#xff1f; 尤其是那个名字如雷贯耳的 OpenAI&#xff0c;简直就是AI界的弄潮儿&#xff0c;一举一动都牵动着我们这些“AI发…...

mac docker部署jar包流程

mac docker部署jar包流程 默认服务器已经准备好了相关的准备工作&#xff0c;如&#xff1a;docker&#xff0c;docker内安装所需软件数据库&#xff0c;jdk等&#xff0c;将要部署等jar包。 1:将jar 包上传到服务器目录下&#xff1a;/usr/local/service (没有目录可以自己创建…...

【postgresql 物化视图】自动刷新物化视图2种方法

普通视图就是一个虚拟表&#xff0c;不占内存。而物化视图是存在的&#xff0c;占内存。 物化视图&#xff0c;默认是手动刷新。下面是手动刷新的例子。我们来创建一个物化视图。 create MATERIALIZED VIEW dnh_analasis_view as select cjsj,a,b,c,d from table_1; REFRESH …...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...