【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究Spring的核心注解开发和实现指南(Spring5的常见的注解)

news2024/11/26 0:58:03

360全方位渗透和探究Spring的核心注解开发和实现指南

  • Spring的注解介绍
    • 核心基础注解
    • 核心注解分析
        • xml文件的配置
        • configuration的配置
      • @Lazy && @Scope
      • @ComponentScan
        • 添加Controller、Service、Repository
        • 注入到spring容器
          • @ComponentScan多包扫描的属性
          • 排除某些包或者类的扫描
            • 排除过滤:FilterType.ANNOTATION
            • 排除过滤:FilterType.ASSIGNABLE_TYPE
            • 排除过滤:FilterType.CUSTOM
      • @Conditional
      • @Import
        • @Import +普通组件类
        • @Import(value="ImportSelector.class")
        • @Import(value="ImportBeanDefinitionRegistrar.class")
      • @Lookup

Spring的注解介绍

Spring 5.x中常见的注解包括@Controller、@Service、@Repository。当我们研究Spring Boot源码时,会发现实际上提供了更多的注解。了解这些注解对于我们非常重要,尽管目前可能还用不到它们。

核心基础注解

注解功能
@Bean器中注册组件,代替来的标签
@Configuration声明这是一个配置类,替换以前的配置xml文件
@ComponentScan包扫描,扫描@Controller、@Service、@Repository、@Component注入Spring容器中
@Conditional按条件注入
@Primary同类组件如果多个,标注主组件
@Lazy组件懒加载(最后使用的时候才创建)
@Scope声明组件的作用范围(SCOPE_PROTOTYPE, SCOPE_SINGLETON)
@DependsOn组件之间声明依赖关系
@Component@Controller、@Service、@Repository的通用注解
@Indexed加速注解,所有标注了 @Indexed 的组件直接会启动快速加载
@Order数字越小优先级越高,越先工作
@Import导入第三方JAR包中的组,或定制批量导入组件逻
@ImportResource导入以前的XML配置文件,让其生效
@Profile基于多环境激活
@PropertySource外部properties配置文件和JavaBean进行绑定,结合ConfigurationProperties
@PropertySources@PropertySource组合注解
@Autowired自动装
@Qualifier精确指定
@Value取值、计算机环境变量、JVM系统。@Value(“$”)
@Lookup单例组件依赖非单例组件,非单例组件获取需要使用方法

注意:@Indexed 需要引入依赖org.springframework spring-context-indexer true

核心注解分析

在这里插入图片描述### @Configuration和@Bean

在早期的Spring项目中,我们通常需要创建一个名为springContext.xml的配置文件,并通过标签进行注入。然而,通过使用 @Configuration 注解,我们可以将一个普通的Java类充当配置文件,取代了繁琐的xml配置。而使用 @Bean 注解则可以替代原来的 标签。

xml文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="beanSample" class="com.xxx.xxx.BeanSample"></bean>
</beans>

configuration的配置

@Configuration
public class SpringConfig {
    @Bean("beanSample")
    BeanSample beanSample() {
        return new BeanSample ();
    }
}

public class SpringTest {
    @Test
    public void beanSample() {
        // 通过配置文件的方式获取所有的bean
        ApplicationContext context = new ClassPathXmlApplicationContext("springContext.xml");
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("xml=>" + beanDefinitionName);
        }
        // 最后打印:xml=>user
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        String[] beanDefinitionName = annotationConfigApplicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionName) {
            System.out.println("annotation = > " + name);
        }
        // 最后打印去处默认配置后:
        // annotation = > springConfig
		// annotation = > beanSample
    }
}

注意:@Bean配置的时候,方法名为默认的id类型,当然也可以@Bean(“id”)这样来指定id。另外,@Bean注入的对象默认都是单例的。

@Lazy && @Scope

如前所述,通过使用@Bean注解,我们可以将对象直接注册到容器中。那么如何设置注册的对象为原型作用域呢?是否可以进行懒加载呢?

首先,要将注册的对象设置为原型作用域,只需要在 @Bean 注解上添加 @Scope(“prototype”) 即可。这样,每次从容器中获取该对象时,都会创建一个新的实例。

// SpringConfig.class
/**
 * @Scope可选内容为:
 * ConfigurableBeanFactory#SCOPE_PROTOTYPE  原型模式
 * ConfigurableBeanFactory#SCOPE_SINGLETON  单例模式
 * org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request模式,同一次强求一个对象
 * org.springframework.web.context.WebApplicationContext#SCOPE_SESSION session模式,同一个session一个对象
 */
@Bean("beanSample")
@Scope("prototype")
BeanSample beanSample() {
	return new BeanSample ();
}

@Bean("beanSample2")
@Scope("singleton")
BeanSample beanSample2() {
	return new BeanSample();
}

// SpringTest.class
BeanSample beanSample = (BeanSample ) annotationConfigApplicationContext.getBean("beanSample");
BeanSample beanSample2 = (BeanSample ) annotationConfigApplicationContext.getBean("beanSample2");
/**
 * 当@Scope("singleton")时,为false
 * 当@Scope("prototype")时,为true
 */
System.out.println(beanSample == beanSample2 ); 

懒加载的支持需要根据具体情况进行配置。默认情况下,使用 @Bean 注解注册的对象是在容器启动时就初始化的,即默认是立即加载的。@Lazy只是在单例模式下使用,让对象需要创建的时候才注入到容器。

如果希望将其设置为懒加载,可以在 @Bean 注解上添加 @Lazy 注解。通过 @Bean 注解不仅可以注册对象到容器中,还可以方便地设置对象的作用域和加载策略。

@ComponentScan

在最早使用Spring项目时,我们不需要将 @Controller、@Service、@Repository 这些注解添加到Spring容器中。为了将这些类加载到Spring容器中,我们通常使用了一个包扫描的配置。使用<context:component-scan base-package="com.xxx"> 这个注解来扫描指定包下的类,将其加载到Spring容器中。

@ComponentScan注解相当于 <context:component-scan> 注解,它能够自动扫描指定包及其子包下的类,并将其注册到Spring容器中。

添加Controller、Service、Repository

@Controller
public class UserController {}
@Service
public class UserService {}
@Repository
public class UserDao {}

注入到spring容器

在SpringConfig的类上添加 @ComponentScan(value = “com.xxx”),Controller、Service、Dao也注入到spring容器中了使用 @ComponentScan 注解可以方便地配置要扫描的包,并将注解类自动加载到Spring容器中。

@ComponentScan多包扫描的属性

当你想扫描多个包的时候,你可以配置value为一个数组。

@ComponentScan(value = {"com.xxx.a", "com.xxx.b"})
排除某些包或者类的扫描

如果你不想让某个包或注解被扫描到,可以在 @ComponentScan 注解中使用 excludeFilters 属性。

在 excludeFilters 中,有几种常见的 Filter 类型可供选择:

  • FilterType.ANNOTATION:根据注解类型进行过滤
  • FilterType.ASSIGNABLE_TYPE:根据给定的类型进行过滤
  • FilterType.CUSTOM:自定义过滤规则

利用这些 Filter 类型,你可以灵活地控制应该排除哪些包或注解,从而更好地管理 Spring 容器中的组件。

排除过滤:FilterType.ANNOTATION

可以使用@ComponentScan注解的excludeFilters 属性来帮助你排除特定的注解。对于你的需求,你可以使用 FilterType.ANNOTATION 类型的过滤器,扫描 com.bearjun 包时排除 @Controller 注解。

具体的实现可以如下所示:

@Configuration
@ComponentScan(
    basePackages = "com.xxx",
    excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
)

在上面的例子中,我们使用了 @ComponentScan 注解来指定需要扫描的基础包为 com.xxx,并使用 excludeFilters 属性来配置过滤器。在过滤器中,我们指定了类型为 FilterType.ANNOTATION,值为 Controller.class,表示要排除所有带有 @Controller 注解的组件。

这样配置之后,Spring 在进行组件扫描时就会排除掉 com.xxx包中带有 @Controller 注解的组件

排除过滤:FilterType.ASSIGNABLE_TYPE

可以使用 @ComponentScan 注解的 excludeFilters 属性来帮助你排除特定的类。对于你的需求,你可以使用 FilterType.ASSIGNABLE_TYPE 类型的过滤器,扫描 com.xxx 包时排除 TestSample 类。

@Configuration
@ComponentScan(
    basePackages = "com.xxx",
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = TestSample.class)
)

在上面的例子中,我们使用了 @ComponentScan 注解来指定需要扫描的基础包为 com.xxx,并使用 excludeFilters 属性来配置过滤器。在过滤器中,我们指定了类型为 FilterType.ASSIGNABLE_TYPE,值为 TestSample.class,表示要排除 TestSample 类。

这样配置之后,Spring 在进行组件扫描时就会排除掉 com.xxx 包中的 TestSample 类。

排除过滤:FilterType.CUSTOM

使用 @ComponentScan 注解的 excludeFilters 属性来帮助你根据自定义的过滤器来排除特定的组件。在这个过程中,你需要实现一个自定义的过滤器 MyFilter,然后根据过滤的逻辑返回 true 或 false。

具体的实现可以如下所示:

@Configuration
@ComponentScan(value = {"com.xxx"}, excludeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM, value = MyFilter.class)
})
  • 下面是一个示例的自定义过滤器 MyFilter 的实现:
// FilterType.CUSTOM类型。
// 自定义一个类,实现 org.springframework.core.type.filter.TypeFilter;
public class MyFilter implements TypeFilter {
    /**
     * @param metadataReader 当前正在扫描的类 ComponentScan value的值的信息
     * @param metadataReaderFactory 获取其他类的信息
     * @return
     */
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
        // 当前类的注解信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        // 当前的扫描的类信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        // 当前类资源
        Resource resource = metadataReader.getResource();
        String className = classMetadata.getClassName();
        // 所有的 controller 返回 true
        if (className.toLowerCase().contains("controller")) {
            return true;
        }
        return false;
    }
}

在上述的示例中,我们使用了 @ComponentScan 注解来指定需要扫描的基础包为 com.xxx,并使用 excludeFilters 属性配置了一个 TYPE 类型为 CUSTOM 的过滤器。过滤器的值为自定义的 MyFilter 类。

在 MyFilter 类中,我们实现了 TypeFilter 接口,并在 match 方法中编写了过滤的逻辑。在示例中的逻辑中,我们判断类名是否以 “Sample” 结尾,如果是,则返回 true,表示要过滤掉该组件。

这样配置之后,Spring 在进行组件扫描时将扫描 com.xxx 包,但根据 MyFilter 的逻辑,满足过滤条件的组件将被排除掉。

@Conditional

使用 @Conditional 注解可以根据一定的条件进行判断,只有满足条件的情况下才会将 Bean 注入到 Spring 容器。

@Configuration
public class SpringConfig {
    @Bean("beanSample")
    BeanSample beanSample() {
        return new BeanSample ();
    }
    @Bean("beanSample2")
    @Conditional(BeanSampleCondition.class)
    BeanSample beanSample2() {
        return new BeanSample ();
    }
}

进行实现对应的判断逻辑条件处理方式。我们定义了 BeanSampleCondition条件类,它们实现了 Condition 接口,并重写了 matches 方法。

public class BeanSampleCondition implements Condition {
    /**
     * @param context  上下文(可以获取各种需要的信息)
     * @param metadata 注释信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        /**
         * 获取bean的注册信息,可以新增,移除,判断。。bean
         */
        BeanDefinitionRegistry registry = context.getRegistry();
        /**
         * 获取项目运行的环境
         */
        Environment environment = context.getEnvironment();
        /**
         * 获取bean工厂
         */
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        /**
         * 获取类加载器活资源加载器
         */
        ClassLoader classLoader = context.getClassLoader();
        ResourceLoader resourceLoader = context.getResourceLoader();
        /**
         * 如果项目中是否存在一个bean叫bear
         */
        return context.getRegistry().containsBeanDefinition("beanSample2");
    }
}

根据系统的操作系统名称我们可以定义我们的判断逻辑,比如示例中判断是否包含 “beanSample2” 命名的bean对象,如果满足条件,则返回 true,表示这个条件成立,对应的 Bean 将被注入到 Spring 容器。根据条件判断,Spring 在初始化时会根据条件的结果来判断是否将对应的 Bean 注入到 Spring 容器。

@Test
public void test1() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    Map<String, User> beansOfType = context.getBeansOfType(User.class);
    beansOfType.forEach((key, value)->{
        System.out.println(key + " ==== " + value);
    });
}

最后输出的结果为:

beanSample ==== BeanSample{}
beanSample2 ==== BeanSample{}

如果我们把@Bean(“beanSample2”)换成@Bean(“beanSample3”),最后的结果为:

beanSample ==== BeanSample{}

@Import

使用 @Import 注解可以引入其他配置类,并将其配置的 Bean 注册到容器中。主要有三种方式分别是一下:

@Import +普通组件类

@Configuration
@ComponentScan(value = "com.bearjun")
@Import(value = {String.class, Math.class})
public class SpringConfig {

}
@Test
public void test3() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    String[] beanDefinitionName = context.getBeanDefinitionNames();
    for (String name : beanDefinitionName) {
    	System.out.println("annotation = > " + name);
	}
}

结果打印存在

annotation = > java.lang.String
annotation = > java.lang.Math

@Import(value=“ImportSelector.class”)

@Configuration
@ComponentScan(value = "com.bearjun")
@Import(value = {MyImportSelector.class})
public class SpringConfig {

}

public class MyImportSelector implements ImportSelector {
    /**
     * @param importingClassMetadata 获取标注了当前@Import注解的所以注解信息
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"java.lang.String"};
    }
}

@Test
public void test3() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    String[] beanDefinitionName = context.getBeanDefinitionNames();
    for (String name : beanDefinitionName) {
    	System.out.println("annotation = > " + name);
	}
}

结果打印存在

annotation = > java.lang.String

@Import(value=“ImportBeanDefinitionRegistrar.class”)

@Configuration
@ComponentScan(value = "com.bearjun")
@Import(value = {ImportBeanDefinitionRegistrar.class})
public class SpringConfig {

}

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * @param importingClassMetadata 当前类的注解信息
     * @param registry               BeanDefinition注册类
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // bean注册器中是否存在bearjun的组件
        if (registry.containsBeanDefinition("bearjun")) {
        	// 往组件中添加id为string的组件
        	BeanDefinition definition = new RootBeanDefinition("java.lang.String");
            registry.registerBeanDefinition("string", definition);
        }
    }
}

@Test
public void test3() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    String[] beanDefinitionName = context.getBeanDefinitionNames();
    for (String name : beanDefinitionName) {
    	System.out.println("annotation = > " + name);
	}
}

结果打印存在

annotation = > java.lang.String

@Lookup

单例组件依赖非单例组件,可以通过调用非单例组件的方法来获取。

  • 使用@Lookup注解时,应将其放置在获取bean的方法上才能生效。
  • 从配置类中返回的bean不能作为单例模式组件(如上述的User类),否则@Lookup注解将不会生效。
@Component
@Scope("prototype")
public class Car {
    private String brand;
    // 省略get/set/toString
}

@Component
public class User {

    private Integer userId;
    private String username;
    private String password;
    private Car car;
    @Lookup
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
}

// SpringTest#test3
@Test
public void test3() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    User user1 = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user1 == user2);
    // 打印:true
    Car car1 = user1.getCar();
    Car car2 = user2.getCar();
    System.out.println(car1 == car2);
}

如果user#getCar不加@Lookup注解,打印为true,加@Lookup注解,打印为false

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

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

相关文章

SpringBoot读取配置的6种方式

1. 概述 通过了解springboot加载配置&#xff0c;可以更方便地封装自定义Starter。 在SpringBoot中&#xff0c;可以使用以下6种方式读取 yml、properties配置&#xff1a; 使用Value注解&#xff1a;读取springboot全局配置文件单个配置。使用Environment接口&#xff1a;通过…

详解c++---异常

目录标题 c语言传统处理错误的方式c异常的使用异常的规则服务器常用的异常继承体系异常安全异常的规范异常的优缺点&#xff1a; c语言传统处理错误的方式 第一种&#xff1a; 程序在运行过程中终止了程序&#xff0c;比如说assert int main() {int i 0;scanf("%d"…

5.5 python函数式编程之--返回函数、匿名函数、偏函数(暂时稍微了解即可)

1、 先回归历史&#xff1a;什么是函数函数就是通过将局部【目标】实现并封装起来&#xff0c; 后续可直接拿来用2、 函数式编程&#xff1a; 是把运算过程尽量写成一系列嵌套的函数调用一、返回函数 返回函数&#xff1a; 函数作为返回值闭包&#xff1a; 函数内部定义函…

OJ练习第138题——树中距离之和

树中距离之和 力扣链接&#xff1a;834. 树中距离之和 题目描述 给定一个无向、连通的树。树中有 n 个标记为 0…n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges &#xff0c; edges[i] [ai, bi]表示树中的节点 ai 和 bi 之间有一条边。 返回长度为 n 的数组 answe…

Vue项目搭建过程

Vue项目搭建过程 1、安装NodeJs 1.1 下载安装包 在 http://nodejs.cn/download/ 上下载64位安装包&#xff0c;然后进行安装&#xff0c;和普通软件的安装一样。 C:\Users\Administrator>node -v v16.13.1C:\Users\Administrator>npm -v 8.5.51.2 安装cnpm # 安装cn…

什么是「推荐系统」,有哪些主要的推荐方法?

1 什么是推荐系统 什么是推荐系统&#xff1f;根据维基百科的定义&#xff0c; 它是一种信息过滤系统&#xff0c;主要功能是预测用户对物品 的评分和偏好。这一定义回答了推荐系统的功能是过滤信息、连接用户和推送信息。将这一定义扩 展一下&#xff0c; 推荐系统就是自动联…

文献阅读:MathPrompter: Mathematical Reasoning using Large Language Models

文献阅读&#xff1a;MathPrompter: Mathematical Reasoning using Large Language Models 1. 内容简介2. 方法细节3. 实验内容4. 结论&思考 文献链接&#xff1a;https://arxiv.org/abs/2303.05398 1. 内容简介 这篇文章是今年3月份的时候微软提出的一篇工作&#xff0…

SpringBoot中间件—ORM(Mybatis)框架实现

目录 定义 需求背景 方案设计 代码展示 UML图 实现细节 测试验证 总结 定义&#xff1a; ORM&#xff1a;Object Relational Mapping --> 对象关系映射&#xff0c;是一种程序设计技术&#xff0c;用于实现面向对象编程语言里面不同类型系统的数据之间的转换 需求背…

前端|CSS(一)| pink老师

参考视频&#xff1a;黑马程序员前端CSS3基础教程&#xff0c;前端必备基础 目录 &#x1f4da;CSS引入 &#x1f407;引入CSS样式表 &#x1f4da;CSS基础选择器 &#x1f407;标签选择器 &#x1f407;类选择器&#xff08;最常用&#xff09; &#x1f407;id选择器 …

VIM文本如何复制到系统剪切板?

今天从vim上用鼠标复制代码&#xff0c;发现把VIM当中的行号也复制进去了&#xff0c;就很麻烦&#xff0c;于是简单研究了下&#xff0c;如果vim支持clipboard的话就比较好办&#xff0c;具体支持与否&#xff0c;使用命令查看&#xff1a; vim --version | grep "clipb…

C语言指针面试题

C语言指针面试题 一.指针和数组1.一维数组2.字符数组3.二维数组 二.指针 一.指针和数组 1.一维数组 int a[] {1,2,3,4};(1)printf("%d\n",sizeof(a));// 16(2)printf("%d\n",sizeof(a0));// 4/8(3)printf("%d\n",sizeof(*a));// 4(4)printf(&…

xred病毒分析

概述 xred病毒是一种感染型病毒&#xff0c;会感染系统中特定目录下的exe和xlsx文件&#xff0c;该病毒会将自身伪装成Synaptics触摸板驱动程序&#xff0c;使用Dephi编写。 样本的基本信息 Verified: Unsigned Link date: 6:22 1992/6/20 Company: Synaptics Description: S…

vue3 前端编码规范

prettier 配置 1. vscode 安装prettier 的 插件 2. 新建 .prettierrc 文件 {"semi": false, // 不尾随分号"singleQuote": true, // 使用单引号"trailingComma": "none" // 多行逗号分隔的语法&#xff0c;最后一行不加逗号 }eslin…

WPF嵌入外部exe应用程序-实现基本的嵌入

WPF嵌入外部exe应用程序 使用场景功能实现嵌入基本功能实现1.导入windows API2.运行外部程序3. 获取窗体句柄4. 嵌入窗体5.设置子窗体位置整个代码 嵌入存在的问题&#xff1a; 使用场景 在WPF桌面应用程序开发过程中&#xff0c;有时候需要将其他程序结合到一起&#xff0c;让…

Linux尖刀——shell

目录 知识点 lsblk grep awk tail du df 对新增存储设备的检测与分区 用lsblk查询块设备 用dmesg看内核打印信息 用ls查看新增设备 对rootfs空间使用情况的监控 知识点 首先想要用shell脚本解决一些问题肯定要熟悉linux的命令 lsblk -t或–tree&#xff1a;以…

Redis进阶底层原理- 缓冲区

Redis中使用了很多缓冲区&#xff0c;在redis各个环节起到了非常核心的作用。下面来一一介绍一下&#xff1a; 输入输出缓冲区&#xff08;客户端缓冲区&#xff09; Redis中的输入输出缓冲区是为了平衡客户端发送命令和服务端处理命令的速度差异&#xff0c;如果客户端发送指…

java用 postman输入 数字 会加上单引号 和逗号,方便查询

java用 postman输入 数字 会加上单引号 和逗号&#xff0c;方便查询 /*** 输入12575726* 891006* 12575726* 891006* 返回* 12575726,* 891006,* 12575726,* 891006* 方便查询数据* param data* return*/RequestMapping(value "l…

MySQL查看系统性能参数、统计SQL的查询成本last_query_cost的使用

1、查看MySQL系统性能参数 在MySQL中&#xff0c;可以使用SHOW STATUS语句查询一些MySQL数据库服务器的性能参数、执行频率。 语法如下&#xff1a; SHOW [ GLOBAL | SESSION] STATUS LIKE 参数; 一些常用的性能参数如下&#xff1a; Connections&#xff1a;连接MySQL服…

《银行法律法规》三、银行管理——2、公司治理、 内部控制与合规管理

第二章 公司治理、 内部控制与合规管理 第一节 公司治理 考点1 银行公司治理概述★★ 商业银行公司治理是指股东大会、 董事会、 监事会、 高级管理层、 股东及其他利益相关者之间的相互关系&#xff0c; 包括组织架构、 职责边界、 履职要求等治理制衡机制&#xff0c; 以…