Spring bean标签

目录

  • Spring bean标签
    • 1.了解Spring Xml配置文件
    • 2.bean标签的Attrbute
    • 3.bean的子标签
    • 扩展
      • FactoryBean

Spring bean标签

在创建IOC容器的时候,是如何把配置文件解析成我们的BeanDefinition。本文针对其<bean/>标签中的属性及其子标签进行说明。

1.了解Spring Xml配置文件

当我们需要去创建一个Spring配置文件的时候我们需要用到这个<beans/>跟根标签,只有在beans下面定义的信息才可以被Spring解析并保存到BeanDefinition中。

先了解一下大致结构。外层是根节点<beans/>,内层是一个一个的<bean/>标签。

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

2.bean标签的Attrbute

源码中是通过这一个方法来解析的。

org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;

parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

  • id:bean的唯一标识,不可重复。

  • name:bean的名称,不可重复。但是允许有多个可以通过,或者;来分割。

  • class: bean的类型,IOC容器会通过这个class来通过反射来创建这个对象。

  • singleton:标识Bean对象在IOC容器中是否是单例的。已弃用。新版采用scope属性来替换。

  • scope:bean的作用域。

    • singleton(默认):在IOC容器中的是单例的。当bean被其他多个bean所依赖的时候。其他都是依赖的同一样。

      <bean id="messageService" name="messageService" class="com.mfyuan.service.MessageServiceImpl"/>
      
      MessageService messageService = applicationContext.getBean("messageService", MessageService.class);System.out.println(messageService);messageService = applicationContext.getBean("messageService", MessageService.class);System.out.println(messageService);
      // 同时输出两个NotifyUtil的MessageServcie 根据内存地址判断为同一个并
      com.mfyuan.service.MessageServiceImpl@675d3402
      com.mfyuan.service.MessageServiceImpl@675d3402
      
    • prototype:原形的。表示当其他多个bean依赖该bean时,与单例不同的是他会创建一个新的实例去被依赖。

      <!--scope改为prototype后-->
      <bean id="messageService" name="messageService" class="com.mfyuan.service.MessageServiceImpl" scope="prototype"/>
      
      // 两个对象不同
      com.mfyuan.service.MessageServiceImpl@675d3402
      com.mfyuan.service.MessageServiceImpl@51565ec2
      
    • request(web扩展的):每一个请求都会去创建不同bean,请求结束后销毁bean。

    • session(web扩展的):不同的session会创建不同bean,session结束后销毁bean。

    • application(web扩展的):不同的web Application会创建,不同bean,webApplication关闭后销毁bean。

  • abstract:抽象的bean,默认为false。为true时,表示该beanIOC容器启动的时候不会去初始化它。只会当做一个配置模版,可以被其他beanparent属性使用。

  • lazy-init:懒加载。默认为false,实时加载。为true时,表示为延时加载的,只有当该beanIOC容器中被使用或者被依赖的时候,才会去创建出这个bean

  • autowire:依赖注入的方式。通常有以下几种

    • no(默认):不采用autowire的机制。当我们需要依赖其他bean时,通过ref来引入其他bean

    • byName:通过属性的名称来自动装配,可以免去使用<property/>。它会自动根据属性名帮忙找到同样名称的bean帮我们注入到当前bean中。没有找到则不会注入

      <bean id="notifyUtil"  class="com.mfyuan.util.NotifyUtil" autowire="byName"/>
      
    • byType:通过类型来自动装配。它会自动根据属性类型帮忙找到类型的bean帮我们注入到当前bean中。如果有多个同样类型的bean会报错。可以使用primary来指定那个是主要的。没有找到则不会注入

      <bean id="notifyUtil"  class="com.mfyuan.util.NotifyUtil" autowire="byType"/>
      
    • constructor:通过构造器来自动装配。他会通过构造器的参数去帮我们找到同样的类型bean来创建当前bean。跟byType类似。但是如何没有找到合适bean来注入的话,则会报错。

    • default:采取父级标签(<beans />)的default-autowire

  • dependency-check:依赖检查。有以下几种:

    • none:即使不注入全部bean属性,也可以将bean创建成功。
    • simple:检查基本对象或者集合类<基本对象>没有注入则会报错。
    • objects:检查引用类型没有注入则会报错。
    • all:检查全部属性是否注入成功。
  • depends-on:设置当前bean依赖那些bean,可以是多个使用,;分割。依赖的这些bean在当前bean前初始化,在当前bean后销毁。

  • autowire-candidate:是否为候选的bean,默认为true。也就是是否可以被其他bean所依赖(只针对于byType,对于byName,不管这个值是true还是false都会注入成功)。

    @Data
    @ToString
    public class NotifyListUtil {private List<MessageService> messageServiceList;
    }
    
    <!--创建了两个MessageService-->
    <bean id="messageService" name="messageService" class="com.mfyuan.service.MessageServiceImpl"/><bean id="messageService1"  class="com.mfyuan.service.MessageServiceImpl"/><bean id="notifyListUtil" class="com.mfyuan.util.NotifyListUtil" autowire="byType"/>
    
    NotifyListUtil notifyListUtil  = applicationContext.getBean("notifyListUtil", NotifyListUtil.class);
    System.out.println(notifyListUtil);
    // 输出 两个
    NotifyListUtil(messageServiceList=[com.mfyuan.service.MessageServiceImpl@e25b2fe, com.mfyuan.service.MessageServiceImpl@754ba872])
    
    <!--将其中一个改为false-->
    <bean id="messageService1"  class="com.mfyuan.service.MessageServiceImpl" autowire-candidate="false"/>
    
    // 输出一个
    NotifyListUtil(messageServiceList=[com.mfyuan.service.MessageServiceImpl@e25b2fe])
    
    <!--autowire改为byName-->
    <bean id="notifyListUtil" class="com.mfyuan.util.NotifyListUtil" autowire="byName"/>
    
    // 输出 0个 为什么呢?因为我这里的属性名是messageServiceList没有为该名称的bean所有就为0个。
    // 思考为什么byName会使这个属性失效了。我们只要知道的是beanName是不允许重复的就能明白了。
    
  • primary:是否为主要的。默认为false。当同时有多个同样类型的bean时,优先注入primarytrue的。

  • init-method:bean初始化的方法。

  • destroy-method:bean销毁的方法。

  • factory-method:分情况

    • 单独使用factory-method的时候。指定class中的一个静态方法来创建这个bean。创建出来的bean,不再是class,而是指定静态方法返回值

      public class MyFactoryMethod {public static String getFactoryMethod(){return "myFactoryMethod";}public static String getFactoryMethod(String methodName){return methodName;}
      }
      
      <bean id="myFactoryMethod" class="com.mfyuan.factory.MyFactoryMethod"/>
      <!--使用factory-method 来创建这个bean对象,而不是创建一个class的bean对象-->
      <bean id="myFactoryMethodStr" class="com.mfyuan.factory.MyFactoryMethod" factory-method="getFactoryMethod"/><!--如果这个静态方法有参数的话,也可以通过constructor-arg 来指定参数-->
      <bean id="myFactoryMethodStr1" class="com.mfyuan.factory.MyFactoryMethod" factory-method="getFactoryMethod"><constructor-arg index="0" value="consumeMethod"/>
      </bean>
      
      Class<?> myFactoryMethod = applicationContext.getType("myFactoryMethod");
      System.out.println(myFactoryMethod);Class<?> myFactoryMethodStr = applicationContext.getType("myFactoryMethodStr");
      System.out.println(myFactoryMethodStr);Object myFactoryMethodStr1 = applicationContext.getBean("myFactoryMethodStr1");
      System.out.println(myFactoryMethodStr1);
      // 输出 一个为class指定的对象,一个则是String。
      class com.mfyuan.factory.MyFactoryMethod
      class java.lang.String
      consumeMethod
      
    • factory-bean一起使用的时候。指定factory-bean中的一个非静态方法class可以省去了。

      public class MyFactoryMethod {public String consumeMethod(){return "consumeMethod";}
      }
      
      <bean id="myFactoryMethod" class="com.mfyuan.factory.MyFactoryMethod"/>
      <!- 通过指定factory-bean工厂bean,及指定一个factory-method来生成实际的bean对象 ->
      <bean id="myFactoryMethodStr2" factory-bean="myFactoryMethod" factory-method="consumeMethod"/>
      
      Object myFactoryMethodStr1 = applicationContext.getBean("myFactoryMethodStr2");
      System.out.println(myFactoryMethodStr2);
      // 输出consumeMethod
      
  • factory-bean:通过指定factory-bean工厂bean,及指定一个factory-method来生成实际的bean对象。为什么使用factory-beanfactory-method必须是非静态的了?这个也很好理解,如果是静态的,直接使用class+factory-method即可。

3.bean的子标签

子标签,也就是xmlbean这个dom元素的子节点;

例如

<bean><description>hello description</description><meta key="info" value="我是一个bean"/>
<bean/>
  • description:bean的一个描述。

  • meta:bean的元信息(可以存在多个)。

    • 源码中由此parseMetaElements(ele, bd);方法进行解析;
  • lookup-method:不常用,但是说一下。

    可以重写bean中的一个方法,把方法的返回值替换成bean指定的对象。要求是返回值与指定的对象类型相同。

    源码中由parseLookupOverrideSubElements(ele, bd.getMethodOverrides());处理

    使用场景。在一个单例对象中,我需要他的一个属性原形的。

    实体类

    @Getter
    @Setter
    public  class MyLockUpMethod {private User refreshUser;
    }
    

    配置文件

    <!--我们定义了一个User,他的scope是prototype 也就是在依赖注入的时候每次都注入的一个新的对象-->
    <bean id="mfyuan" class="com.mfyuan.model.User" scope="prototype"><property name="name" value="mfYuan" />
    </bean>
    <!-- 将mfyuan这个bean注入到myLockUpMethod中-->
    <bean id="myLockUpMethod" class="com.mfyuan.component.MyLockUpMethod" ><property name="refreshUser" ref="mfyuan"></property>
    </bean>
    

    操作类

    MyLockUpMethod myLockUpMethod = applicationContext.getBean("myLockUpMethod",MyLockUpMethod.class);
    System.out.println(myLockUpMethod+"-"+myLockUpMethod.getRefreshUser());
    myLockUpMethod = applicationContext.getBean("myLockUpMethod",MyLockUpMethod.class);
    System.out.println(myLockUpMethod+"-"+myLockUpMethod.getRefreshUser());
    // 输出 这两个对象的refreshUser是相同的,
    com.mfyuan.component.MyLockUpMethod@39c0f4a-com.mfyuan.model.User@39c0f4a
    com.mfyuan.component.MyLockUpMethod@39c0f4a-com.mfyuan.model.User@39c0f4a
    

    这个结果也很好能理解,因为我们的MyLockUpMethod是单例的。所以每次从IOC容器中取的是一个对象。其属性也自然想同。

    修改配置文件

    <!-- 将myLockUpMethod的scope也改原形的-->
    <bean id="myLockUpMethod" class="com.mfyuan.component.MyLockUpMethod" scope="prototype"><property name="refreshUser" ref="mfyuan"></property>
    </bean>6
    // 输出不同,但是这样无法保证myLockUpMethod是同一个对象。
    com.mfyuan.component.MyLockUpMethod@39c0f4a-com.mfyuan.model.User@1794d431
    com.mfyuan.component.MyLockUpMethod@42e26948-com.mfyuan.model.User@57baeedf
    

    修改配置文件

    <bean id="myLockUpMethod" class="com.mfyuan.component.MyLockUpMethod"><lookup-method  name="getRefreshUser" bean="mfyuan"/>
    </bean>
    // 满足要求MyLockUpMethod相同Uesr不同。
    com.mfyuan.component.MyLockUpMethod$$EnhancerBySpringCGLIB$$af152e52@e320068-com.mfyuan.model.User@1f57539
    com.mfyuan.component.MyLockUpMethod$$EnhancerBySpringCGLIB$$af152e52@e320068-com.mfyuan.model.User@76f2b07d
    

    可以看见他这里是使用的CGLIB代理来创建的myLockUpMethod,通过去代理并重写getRefreshUser,来实现。

  • replaced-method:方法替换,相比lockup-method,更灵活一点。就相当于重写方法。

    源码中由parseReplacedMethodSubElements(ele, bd.getMethodOverrides())来解析。

    <bean id="xxx" class="xxx"><replaced-method name="xxx" replacer="xxx"><arg-type match=""></arg-type></replaced-method>
    </bean>
    

    <bean/>内允许有多个<replaced-method/>,其name属性为要重写的方法名称,replacer为实现了MethodReplacer的实现类,具体替换逻辑在reimplement中编写。如果需要重写的方法有重载的情况的话可以通过<arg-type/>指定类型,从而找到目标方法。

    public interface MethodReplacer {/*** 重新实现给定的方法。* @param obj 被替换方法的对象* @param method 要替换的方法* @param args 方法的参数* @return 方法的返回值*/Object reimplement(Object obj, Method method, Object[] args) throws Throwable;
    }
    

    实体类

    public class Execute {public void execute(){System.out.println("execute...");}
    }
    

    配置文件

    <bean id="execute" class="com.mfyuan.model.Execute">
    

    操作类

    Execute execute = applicationContext.getBean(Execute.class);
    System.out.println(execute);
    execute.execute();
    // 输出
    com.mfyuan.model.Execute@7a1ebcd8
    execute...
    

    实现MethodReplacer

    public class ExecuteReplacer implements MethodReplacer {@Overridepublic Object reimplement(Object obj, Method method, Object[] args) throws Throwable {switch (method.getName()) {case "execute":System.out.println("execute replacer...");}return null;}
    }
    

    修改配置文件

    <!-- 将ExecuteReplacer注入IOC容器。 -->
    <bean id="executeReplacer" class="com.mfyuan.component.ExecuteReplacer"/><bean id="execute" class="com.mfyuan.model.Execute"><!-- 替换execute方法,由executeReplacer来实现。 --><replaced-method name="execute" replacer="executeReplacer"/>
    </bean>
    

    操作类

    // 输出
    com.mfyuan.model.Execute$$EnhancerBySpringCGLIB$$1accf27a@5faeada1
    execute replacer...
    

    方法替换成功,发现这个类也是被CGLIB进行了代理。

    public interface MethodReplacer {/*** 重新实现给定的方法。* @param obj 被替换方法的对象* @param method 要替换的方法* @param args 方法的参数* @return 方法的返回值*/Object reimplement(Object obj, Method method, Object[] args) throws Throwable;
    }
    
  • constructor-arg:用于构造函数注入,或者是factory-bean有参数的时候等。可以通过该标签指定参数。(可以多个)。源码中由parseConstructorArgElements(ele, bd);解析。

  • property(最常用的):指定bean对象的属性值。源码中由parsePropertyElements(ele, bd);解析。

  • qualifier:如果当前beanautowire,并且,当对应的属性找到的多个bean时,可以通过qualifier来指定使用哪一个。

扩展

FactoryBean

又称工厂Bean。那BeanFactory呢?这两者完全不是一种东西。BeanFactory可以把他理解为就是一个IOC容器,而FactroyBean的话则是一种特殊Bean。类似<bean/>里的factory-bean,与factory-method。而FactoryBean的话则不需要去指定这个,直接通过class使用即可。

FactoryBean源码

public interface FactoryBean<T> {/*** 工厂Bean返回的对象实例* @return an instance of the bean (can be {@code null})* @throws Exception in case of creation errors* @see FactoryBeanNotInitializedException*/T getObject() throws Exception;/*** 返回对象实例的类型* @return the type of object that this FactoryBean creates,* or {@code null} if not known at the time of the call* @see ListableBeanFactory#getBeansOfType*/Class<?> getObjectType();/*** 返回的实例是否单例的,* @return whether the exposed object is a singleton* @see #getObject()* @see SmartFactoryBean#isPrototype()*/boolean isSingleton();
}

实现一个FactoryBean

@Data
public class UserFactoryBean implements FactoryBean<User> {private String userName;public UserFactoryBean(String userName) {this.userName = userName;}@Overridepublic User getObject() throws Exception {return new User(userName);}@Overridepublic Class<?> getObjectType() {return User.class;}@Overridepublic boolean isSingleton() {return false;}
}

配置文件

<bean id="userFactoryBean" class="com.mfyuan.factory.UserFactoryBean" ><constructor-arg index="0" value="xiaoChen" />
</bean>

输出

Object userFactoryBean = applicationContext.getBean("userFactoryBean");
System.out.println(userFactoryBean);
// User(name=xiaoChen)// 通过&可以拿到UserFactoryBean本身的这个对象。
userFactoryBean = applicationContext.getBean("&userFactoryBean");
System.out.println(userFactoryBean);
// UserFactoryBean(userName=xiaoChen)

让我们在IOC容器中去注入一个FactoryBean对象的时候,其实是为我们注入了两个对象,其一是getObject()返回值,其二是FactroyBean本身这个对象。通过&+beanName可以取到FactoryBean本身的这个对象。

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

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

相关文章

ElasticSearch搜索详细讲解与操作

全文检索基础 全文检索流程 流程&#xff1a; 创建索引 返回结果 查询索引 原始文档 创建索引 索引库 查询索引 创建索引&#xff1a; 获取文档 构建文档对象 分析文档分词 创建索引 查询索引&#xff1a; 用户查询结构 创建查询 执行查询 渲染结果 相关概念 索引库 索引库就…

在 uniapp 中 一键转换单位 (px 转 rpx)

在 uniapp 中 一键转换单位 px 转 rpx Uni-app 官方转换位置利用【px2rpx】插件Ctrl S一键全部转换下载插件修改插件 Uni-app 官方转换位置 首先在App.vue中输入这个&#xff1a; uni.getSystemInfo({success(res) {console.log("屏幕宽度", res.screenWidth) //屏…

酷柚易汛ERP - 商品库存余额表操作指南

1、应用场景 商品库存余额表用于查询商品在各仓库的实际结存量、单位成本以及成本等明细。 2、主要操作 打开【仓库】-【商品库存余额表】&#xff0c;可筛选仓库、商品、商品类别&#xff0c;导出/打印等操作见【销货单】不再赘述。 3、分享操作 库存余额分享&#xff0c;…

CCLink转Modbus TCP网关_MODBUS网口设置

兴达易控CCLink转Modbus TCP网关是一种用于连接CCLink网络和Modbus TCP网络的设备。它提供了简单易用的MODBUS网口设置&#xff0c;可以帮助用户轻松地配置和管理网络连接 1 、网关做为MODBUS主站 &#xff08;1&#xff09;将电脑用网线连接至网关的P3网口上。 &#xff08;…

计算机网络(一)

一、什么是计算机网络、计算机协议&#xff1f; 计算机网络就是由计算机作为收发端&#xff0c;不同计算机相互连接的网络&#xff0c;包括互联网&#xff08;Internet&#xff09;&#xff0c;公司或者家用网络&#xff08;intranet&#xff09;等等&#xff1b;其中Internet…

【C语言 | 指针】C指针详解(经典,非常详细)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【数据结构】非递归实现二叉树的前 + 中 + 后 + 层序遍历(听说面试会考?)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&…

利用角色roles上线wordpress项目

角色订制&#xff1a;roles ① 简介 对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。   roles 用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文…

CentOS7、CentOS8 如何修改ip信息(修改网络信息)(无图形界面)(亲测可用)

文章目录 CentOS 7方法一&#xff1a;使用 nmcli 命令方法二&#xff1a;编辑配置文件&#xff08;我的CentOS7是使用这种方法&#xff0c;亲测可用&#xff09; CentOS 8方法一&#xff1a;使用 nmcli 命令方法二&#xff1a;编辑配置文件 在 CentOS 系统中&#xff0c;如果你…

详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await

同步&异步的概念 在讲这四种异步方案之前&#xff0c;我们先来明确一下同步和异步的概念&#xff1a; 所谓同步(synchronization)&#xff0c;简单来说&#xff0c;就是顺序执行&#xff0c;指的是同一时间只能做一件事情&#xff0c;只有目前正在执行的事情做完之后&am…

Halcon WPF 开发学习笔记(2):Halcon导出c#脚本和WPF初步开发

文章目录 前言HalconC#教学简单说明如何二开机器视觉如何二次开发Halcon导出Halcon脚本新建WPF项目&#xff0c;导入Halcon脚本和Halcon命名空间 前言 我目前搜了一下我了解的机器视觉软件&#xff0c;有如下特点 优点缺点兼容性教学视频(B站前三播放量)OpenCV开源&#xff0…

Vue 组件化编程 和 生命周期

目录 一、组件化编程 1.基本介绍 : 2.原理示意图 : 3.全局组件示例 : 4.局部组件示例 : 5.全局组件和局部组件的区别 : 二、生命周期 1.基本介绍 : 2.生命周期示意图 : 3.实例测试 : 一、组件化编程 1.基本介绍 : (1) 开发大型应用的时候&#xff0c;页面往往划分成…

Flink之Java Table API的使用

Java Table API的使用 使用Java Table API开发添加依赖创建表环境创建表查询表输出表使用示例 表和流的转换流DataStream转换成表Table表Table转换成流DataStream示例数据类型 自定义函数UDF标量函数表函数聚合函数表聚合函数 API方法汇总基本方法列操作聚合操作Joins合并操作排…

智能优化算法(一):伪随机数的产生

文章目录 1.伪随机数介绍1.1.伪随机产生的意义1.2.伪随机产生的过程 2.产生U(0,1)的乘除同余法2.1.原始的乘同余法2.2.改进的乘同余法 3.产生正态分布的伪随机数4.基于逆变法产生伪随机数 1.伪随机数介绍 1.1.伪随机产生的意义 1.随机数的产生是进行随机优化的第一步也是最重要…

Qt QTableWidget表格的宽度

本文归属于 Qt实验室-CSDN博客 系列文章 默认值 QTableWIdget的表格宽度默认是一个给定值&#xff0c;可以手动调整每列的宽度&#xff0c;也不填满父窗口 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {this->resize(800,600);QStringList contents{&q…

2023.11-9 hive数据仓库,概念,架构,元数据管理模式

目录 0.数据仓库和数据库 数据仓库和数据库的区别 数据仓库基础三层架构 一.HDFS、HBase、Hive的区别 二.大数据相关软件 三. Hive 的优缺点 1&#xff09;优点 2&#xff09;缺点 四. Hive 和数据库比较 1&#xff09;查询语言 2&#xff09;数据更新 3&#xff09;…

《视觉SLAM十四讲》-- 相机与图像

04 相机与图像 4.1 相机模型 4.1.1 针孔相机模型 针孔模型描述了一束光线通过针孔后&#xff0c;在针孔背面投影成像的关系&#xff08;类似小孔成像原理&#xff09;。 根据相似三角关系 Z f − X X ′ − Y Y ′ (3-1) \frac{Z}{f}-\frac{X}{X^{\prime}}-\frac{Y}{Y^{\p…

UART学习

uart.c #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h" // UART4_TX : PG11 AF6 // UART4_RX : PB2 AF8 void __uart_init() {// GPIOB2 设置为复用功能GPIOB->MODER & (~(0x3 << 4));GPIOB->MODER | (0x2 << 4);G…

5.图层控制器(DefaultOverlayManager)

愿你出走半生,归来仍是少年&#xff01; 图层控制器用于操作在MapView中的图层。 1.图层新增 voidadd(int pIndex, Overlay pElement)List<Overlay>overlays() 通过add方法可向MapView中新增一个图层&#xff0c;并指定其顺序。或者通过获取其图层的List,进行操作新增。…

算法与数据结构--前缀和

一维前缀和适用于计算某个一维数列某个数到某个数之间的累加和&#xff08;或者乘积&#xff0c;又或者异或和&#xff09;之类的。 比如计算某个一维度数列从i到j之间元素的和。最开始的想法就是从i遍历到j&#xff0c;将这之间的元素相加。但是当查询次数很多时候&#xff0…