【Spring】Spring IOCDI:架构旋律中的“依赖交响”与“控制华章”

前言

🌟🌟本期讲解关于Spring IOC&DI的详细介绍~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力                                       

🎆那么废话不多说直接开整吧~~

 

目录

📚️1.IOC&DI入门 

1.1什么是Spring

1.2什么是IOC

1.3IOC的介绍

1.3.1传统的开发过程

1.3.2IOC程序开发 

1.3.3IOC的优势

1.4DI的介绍

📚️2.IOC&DI的使用

📚️3.IOC详解

3.1Bean的存储

3.2类注解实现

3.3获取Bean的其他方式

3.4多种注解含义

3.5方法注解Bean

3.5.1方法注解要配合注解类

3.5.2存在多个对象

📚️4.DI详解

4.1属性的注入

4.2构造方法注入

4.3setter方式注入

4.4几种方式的优缺

4.5@Autowired的缺点

4.5.1使用@Primary

4.5.2使用@Qualifier

4.5.3使用@Resource

📚️5.总结


 

📚️1.IOC&DI入门 

1.1什么是Spring

通过前⾯的学习, 我们知道了Spring是⼀个开源框架, 他让我们的开发更加简单. 他⽀持⼴泛的应⽤场景, 有着活跃⽽庞⼤的社区, 这也是Spring能够⻓久不衰的原因.但是这个概念相对来说, 还是⽐较抽象.

我们⽤⼀句更具体的话来概括Spring, 那就是: Spring 是包含了众多⼯具⽅法的 IoC 容器 

1.2什么是IOC

在前⾯讲到, 在类上⾯添加 @RestController 和@Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类. 把对象交给Spring管理, 就是IoC思想

IOC:: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器

控制反转:

当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了

总结:

IOC就是一个创建任务对象的容器;

DI就是我们后面需要注入的依赖

1.3IOC的介绍

1.3.1传统的开发过程

假如我们在实现创建一个车子的时候,我们知道他是依赖于车身,轮胎,底盘...那么就有如下的依赖的情况:

那么我们在程序实现的时候就是如下所示的:

public class Car {//车依赖于车身private Framwork framwork;public Car(int size) {framwork = new Framwork(size);System.out.println("Car init....");}public void run(){System.out.println("car run....");}
}

 解释:

这就是车在制造的时候,依赖车身,所以就会创建一个车身的对象,那但是此时车身依赖由于底盘,就会在车身类进行对象的构造;

public class Framwork {private Bottem bottem;public Framwork(int size){bottem=new Bottem(size);System.out.println("framwork init....");}
}

解释:

此时我们就会发现,车身的制造依赖于底盘,那么就要创建底盘的对象,那么此时一直到最后一环指定就是轮胎;

public class Tire {private int size;public Tire(int size){this.size=size;System.out.println("tire init...");}
}

解释:

如果这里我们这里,最后一环的情况下,假如我们要规定颜色和轮胎的尺寸大小,此时就会发现一个问题;

以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改.程序的耦合度⾮常⾼(修改⼀处代码, 影响其他处的代码修改)

1.3.2IOC程序开发 

此时我们就可以使用IOC程序开发的思想进行改进,将整个对象进行统一管理,然后就可以大大降低耦合性;

public static void main(String[] args) {Tire tire = new Tire(20);Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}
static class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("Car init....");}public void run() {System.out.println("Car run...");}
}

 解释:

这里小编只展示了一小部分,其余的写法基本是一致的;代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了

1.3.3IOC的优势

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制了 

那么此时就可以看做是如下所示的情况:

 

此时优点就是如下:

1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了
2. 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度. 

1.4DI的介绍

DI: Dependency Injection(依赖注⼊) 

容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊。程序运⾏时需要某个资源,此时容器就为其提供这个资源.

 

就是一个依赖的注入;

IoC 是⼀种思想,也是"⽬标", ⽽思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI 就属于具体的实现。所以也可以说, DI 是IoC的⼀种实现

📚️2.IOC&DI的使用

既然 Spring 是⼀个 IoC(控制反转)容器,作为容器, 那么它就具备两个最基础的功能:
• 存
• 取
Spring 容器 管理的主要是对象, 这些对象, 我们称之为"Bean". 我们把这些对象交由Spring管理, 由
Spring来负责对象的创建和销毁. 我们程序只需要告诉Spring, 哪些需要存, 以及如何从Spring中取出对象

此时我们就会使用@component来进行管理Bean,使用@Autowired来进行依赖的注入,那么代码如下:

@Component
public class BookDao {public List<BookInfo> mockData(){List<BookInfo> books=new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}

我们将这个数据对象交给spring管理,就是加上注解@Component;

@Component //交给spring进行管理
public class BookService {@Autowiredprivate BookDao bookDao;public List<BookInfo> getBookList(){List<BookInfo> books=bookDao.mockData();for (BookInfo book : books) {if (book.getStatus() == 1) {book.setStatusCN("可借阅");} else {book.setStatusCN("不可借阅");}}return books;}
}

 这里就是将逻辑处理的对象交给spring管理,由于这里要使用数据,所以要引入依赖,这个依赖就可以将数据的对象传过来;

@RequestMapping("/book")
@RestController
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/getList")public List<BookInfo> getList() {//获取数据//交给spring注入依赖List<BookInfo> books = bookService.getBookList();//处理⻚⾯展⽰return books;}
}

最后在controller表现层操作时,将引入逻辑处理层的对象,此时就可以spring管理的对象拿出来,就是依赖的引入;

📚️3.IOC详解

通过上⾯的案例, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI的操作.前⾯我们提到IoC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象。也就是bean的存储

3.1Bean的存储

在之前的⼊⻔案例中,要把某个对象交给IOC容器管理,需要在类上添加⼀个注解:@Component⽽Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解

1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
2. ⽅法注解:@Bean.

那么下面小编来示范一下;

3.2类注解实现

这里小编就只使用controller进行操作,通过controller注解来进行存储Bean;

代码如下所示:

@Controller
public class UserController {public void userController(){System.out.println("userController start...");}
}

此时我们就将这里的对象给spring进行管理了;

如何从Spring容器中获取对象:

@SpringBootApplication
public class SpringIocDemoApplication {public static void main(String[] args) {//获取Spring上下⽂对象ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);//从Spring上下⽂中获取对象UserController userController = context.getBean(UserController.class);//使⽤对象userController.sayHi();}
}
解释:
ApplicationContext 翻译过来就是: Spring 上下⽂因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下⽂
这个上下⽂, 就是指当前的运⾏环境, 也可以看作是⼀个容器, 容器⾥存了很多内容, 这些内容是当前运⾏的环境
可以看到此时的对象就是拿到了的,即输出了usercontroller start这句话~~~

然后我们将这个controller进行删除试试:

 此时就是出现异常了:就是这不到这个类型对象的存在,所以就抛出了异常;

3.3获取Bean的其他方式

上述就是通过类型来进行获取Bean的;

上述代码是根据类型来查找对象, 如果Spring容器中, 同⼀个类型存在多个bean的话, 怎么来获取呢?

ApplicationContext 也提供了其他获取bean的⽅式, ApplicationContext 获取bean对象的功能, 是⽗类BeanFactory提供的功能.

public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

可以看到这里可以根据类型和名字进行对象的获取,那么Bean的名字是啥?

Spring bean是Spring框架在运⾏时管理的对象, Spring会给管理的对象起⼀个名字,给每个对象起⼀个名字, 根据Bean的名称(BeanId)就可以获取到对应的对象.

Bean的命名

官方的文档就是如下所示:

具体的内容就是:

命名约定使⽤Java标准约定作为实例字段名. 也就是说,bean名称以⼩写字⺟开头,然后使⽤驼峰式⼤⼩写 ;

类名: UserController, Bean的名称为: userController
类名: AccountManager, Bean的名称为: accountManager

当然也有特殊的情况,前面两个单词都是大写:

类名: UController, Bean的名称为: UController
类名: AManager, Bean的名称为: AManager 

还有就是三个大写字母,的Bean的命名就是:

类名:UserControllerDI,Bean的名称;usercontrollerDI

此时我们使用三种获取Bean的方式进行获取Bean对象:

  public static void main(String[] args) {ApplicationContext context= SpringApplication.run(SpringIocApplication.class, args);UserController bean = context.getBean(UserController.class);bean.userController();UserController bean1 = (UserController) context.getBean("userController");bean1.userController();UserController bean2 = context.getBean("userController",UserController.class);bean2.userController();
}

解释:

此时我们这里第一种获取Bean的方式就是通过类型进行获取,然后第二种就是通过bean的名称进行获取,第三种就是前面两种的合并的方式;

此时我们进入运行状态:

ApplicationContext与BeanFactory

继承关系和功能⽅⾯来说:Spring 容器有两个顶级的接⼝:BeanFactory 和ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ApplicationContext 属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持

 从性能⽅⾯来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,⽽
BeanFactory 是需要那个才去加载那个,因此更加轻量. (空间换时间

这里小编就不再演示其他几个了,基本代码和思想都是一样的~~~

3.4多种注解含义

• @Controller:控制层, 接收请求, 对请求进⾏处理, 并进⾏响应.
• @Servie:业务逻辑层, 处理具体的业务逻辑.
• @Repository:数据访问层,也称为持久层. 负责数据访问操作
• @Configuration:配置层. 处理项⽬中的⼀些配置信息

类注解之间的关系查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发
现:

这些注解⾥⾯都有⼀个注解 @Component ,说明它们本⾝就是属于 @Component 的"⼦类".
@Component 是⼀个元注解,这些其他的注解就是@Component的衍生类;

3.5方法注解Bean

1.使⽤外部包⾥的类, 没办法添加类注解
2. ⼀个类, 需要多个对象, ⽐如多个数据源

3.5.1方法注解要配合注解类

代码如下所示:

@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}
}

那么此时就将这个对象进行了管理了;

那么我们就可以拿到这个对象:

UserInfo bean = context.getBean("UserInfo.class");System.out.println(bean);
3.5.2存在多个对象

代码如下:

@Configuration
public class BeanConfig {@Beanpublic UserInfo user1(){return new UserInfo("zhangsan");}//@Primary@Beanpublic UserInfo user2(){return new UserInfo("lisi");}
}

那么此时我们使用类型进行获取时候;

那么此时我们就要通过bean的名称来进行获取了;

User user1 = (User) context.getBean("user1");User user2 = (User) context.getBean("user2")

📚️4.DI详解

依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象.在上⾯程序案例中,我们使⽤了 @Autowired 这个注解,完成了依赖注⼊的操作

1. 属性注⼊(Field Injection)
2. 构造⽅法注⼊(Constructor Injection)
3. Setter 注⼊(Setter Injection)

4.1属性的注入

代码如下:

@Controller
public class UsercontrollerDI {@Autowiredprivate  UserServiceDI userServicedi;//private final UserServiceDI userServiceDI=new UserServiceDI();public void start(){userServicedi.start();}}

这里就是通过属性的注入的方式进行依赖的注入;

此时我们进行对象的获取和打印:

   UsercontrollerDI bean3 = context.getBean(UsercontrollerDI.class);bean3.start();

去掉@Autowired , 再运⾏⼀下程序看看结果:

就是说明了这里由于没有注入依赖,那么就直接为空了(这个对象)

4.2构造方法注入

 代码如下所示:

@Controller
public class UserControllerDI2 {private UserServiceDI userServiceDI;public UserControllerDI2(){}@Autowiredpublic UserControllerDI2(UserServiceDI userServiceDI){this.userServiceDI=userServiceDI;}public void start(){userServiceDI.start();}
}

解释:

这就是通过构造方法来进行操作的,当然这里有点问题就是当存在两个构造方法的时候,默认就是无参的构造方法;

只有一个构造方法的时候,默认是使用这一个

若存在两个构造方法,此时就要指定使用那个构造方法

4.3setter方式注入

这里就和get与set方式基本一致了:

@Controller
public class UserSet {private UserServiceDI userServiceDI;@Autowiredpublic void setUserServiceDI(UserServiceDI userServiceDI) {this.userServiceDI = userServiceDI;}public void start(){userServiceDI.start();}
}

这里小编就不在过多的解释了;

4.4几种方式的优缺

属性注入

◦ 优点: 简洁,使⽤⽅便;
◦ 缺点:
▪ 只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指
针异常)
▪ 不能注⼊⼀个Final修饰的属性

构造函数注入

优点:
▪ 可以注⼊final修饰的属性
▪ 注⼊的对象不会被修改
▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法
是在类加载阶段就会执⾏的⽅法.
▪ 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的
◦ 缺点:
▪ 注⼊多个对象时, 代码会⽐较繁琐

setter方式注入

优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊
◦ 缺点:
▪ 不能注⼊⼀个Final修饰的属性
▪ 注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险

4.5@Autowired的缺点

当出现多个同种类型的对象的时候:

public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}//@Primary@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}
}

此时我们进行注入,就会出现如下的情况:

@Autowiredprivate UserInfo user;public void start(){System.out.println(user);}

直接出错;

很明显就是分不清楚,那个是要注入的Bean;

那么就有下面几种方法;

4.5.1使用@Primary

代码如下:

@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}@Primary@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}

此时我们默认这个对象;

4.5.2使用@Qualifier

注意这里要和autowired进行搭配使用

    @Qualifier("userInfo1")@Autowiredprivate UserInfo user;

这里就要指定那个;

4.5.3使用@Resource

这里和上面一样,只不过不用搭配@Autowired了;

  @Sesource("userInfo1")private UserInfo user;

•@Autowird 与 @Resource的区别
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean.

📚️5.总结

本期小编主要讲解了关于Spring IOC和DI的详细介绍,从入门讲解概念到实际的应用,都有涉及,当然其中还涉及比较重要的面试题哦~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                 😊😊  期待你的关注~~~

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

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

相关文章

44 基于32单片机的博物馆安全监控系统设计

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 检测 分别是温湿度 光照 PM2.5、烟雾、红外&#xff0c;然后用OLED屏幕显示&#xff0c; 红外超过阈值则蜂鸣器报警&#xff0c;这是防盗报警&#xff1b;温度或烟雾超过阈值&#xff0c;则蜂鸣器…

VScode离线下载扩展安装

在使用VScode下在扩展插件时&#xff0c;返现VScode搜索不到插件&#xff0c;网上搜了好多方法&#xff0c;都不是常规操作&#xff0c;解决起来十分麻烦&#xff0c;可以利用离线下载安装的方式安装插件&#xff01;亲测有效&#xff01;&#xff01;&#xff01; 1.找到VScod…

文生视频、图生视频 AI 大模型开源项目介绍【持续更新】

Open-Sora 介绍&#xff1a;Open-Sora是一个由北京大学和兔展科研团队推出的开源项目&#xff0c;旨在推动视频生成技术的发展。Open-Sora致力于高效制作高质量视频&#xff0c;通过开源原则&#xff0c;使高级视频生成技术变得民主化&#xff0c;并提供一个简化且用户友好的平…

Burp Suite 实战指南:Proxy 捕获与修改流量、HTTP History 筛选与分析

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

基于Vue实现的移动端手机商城项目 电商购物网站 成品源码

&#x1f4c2;文章目录 一、&#x1f4d4;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站演示 &#x1f4f8;部分截图 &#x1f3ac;视频演示 五、⚙️网站代码 &#x1f9f1;项目结构 &#x1f492;vue代码预览 六、&#x1f527;完整…

.NET 9 中 LINQ 新增功能实现过程

本文介绍了.NET 9中LINQ新增功能&#xff0c;包括CountBy、AggregateBy和Index方法,并提供了相关代码示例和输出结果&#xff0c;感兴趣的朋友跟随我一起看看吧 LINQ 介绍 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的…

yarn install遇到问题处理

1、Yarn在尝试安装一个依赖项时遇到了问题。具体来说&#xff0c;这个错误指出期望提升&#xff08;hoist&#xff09;的包的manifest文件丢失了&#xff0c;这通常是因为缓存中的数据损坏或不一致所致。 解决方法&#xff1a;有以下两种 1、清除Yarn缓存&#xff1a;运行 yarn…

遇到问题:hive中的数据库和sparksql 操作的数据库不是同一个。

遇到的问题&#xff1a; 1、hive中的数据库和sparksql 操作的数据库不同步。 观察上面的数据库看是否同步 &#xff01;&#xff01;&#xff01; 2、查询服务器中MySQL中hive的数据库&#xff0c;发现创建的位置没有在hdfs上&#xff0c;而是在本地。 这个错误产生的原因是&…

大数据-240 离线数仓 - 广告业务 测试 ADS层数据加载 DataX数据导出到 MySQL

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

计算机网络-网络安全

网络安全介绍 端口扫描 安全包括那些方面&#xff1a; 数据存储安全、应用程序安全、操作系统安全、网络安全、物理安全、用户安全教育 一、网络安全问题概述 1. 计算机网络面临的安全性威胁 计算机网络上的通信面临以下的四种威胁&#xff1a; 截获——从网络上窃听他人…

linux 获取公网流量 tcpdump + python + C++

前言 需求为&#xff0c;统计linux上得上下行公网流量&#xff0c;常规得命令如iftop 、sar、ifstat、nload等只能获取流量得大小&#xff0c;不能区分公私网&#xff0c;所以需要通过抓取网络包并排除私网段才能拿到公网流量。下面提供了一些有效得解决思路&#xff0c;提供了…

【CSS in Depth 2 精译_066】11.2 颜色的定义(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 11 章 颜色与对比】 ✔️ 11.1 通过对比进行交流 11.1.1 模式的建立11.1.2 还原设计稿 11.2 颜色的定义 ✔️ 11.2.1 色域与色彩空间11.2.2 深入理解颜色表示法 文…

论文导读 I RAFT:使语言模型适应特定领域的RAG

摘要 随着大语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;这些模型在广泛的任务中展现出了卓越的性能。然而&#xff0c;当这些模型应用于特定领域时&#xff0c;如何有效融入新信息仍然是一个未解决的问题。本文提出了检索增强微调&#xff08;RAFT&#xff09;&a…

华为HarmonyOS 让应用快速拥有账号能力 -- 2 获取用户头像昵称

场景介绍 如应用需要完善用户头像昵称信息&#xff0c;可使用Account Kit提供的头像昵称授权能力&#xff0c;用户允许应用获取头像昵称后&#xff0c;可快速完成个人信息填写。以下只针对Account kit提供的头像昵称授权能力进行介绍&#xff0c;若要获取头像还可通过场景化控…

高校数字化运营平台解决方案:构建统一的服务大厅、业务平台、办公平台,助力打造智慧校园

教育数字化是建设教育强国的重要基础&#xff0c;利用技术和数据助推高校管理转型&#xff0c;从而更好地支撑教学业务开展。 近年来&#xff0c;国家多次发布政策&#xff0c;驱动教育行业的数字化转型。《“十四五”国家信息化规划》&#xff0c;推进信息技术、智能技术与教育…

华为HarmonyOS 让应用快速拥有账号能力 -- 1 华为账号一键登录

概述 华为账号一键登录是基于OAuth 2.0协议标准和OpenID Connect协议标准构建的OAuth2.0 授权登录系统&#xff0c;应用可以通过华为账号一键登录能力方便地获取华为账号用户的身份标识和手机号&#xff0c;快速建立应用内的用户体系。 优势&#xff1a; 利用系统账号的安全…

C语言:指针与数组

一、. 数组名的理解 int arr[5] { 0,1,2,3,4 }; int* p &arr[0]; 在之前我们知道要取一个数组的首元素地址就可以使用&arr[0]&#xff0c;但其实数组名本身就是地址&#xff0c;而且是数组首元素的地址。在下图中我们就通过测试看出&#xff0c;结果确实如此。 可是…

是什么阻断了kafka与zk的链接?

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 前几天部署一套环境&#xff0c;先把zk集群起来了&#xff0c;之后第二天在启动kafka的时候&#xff0c;…

MAUI APP开发蓝牙协议的经验分享:与跳绳设备对接

在开发MAUI应用程序时&#xff0c;蓝牙协议的应用是一个重要的环节&#xff0c;尤其是在需要与外部设备如智能跳绳进行数据交换的场景中。以下是我在开发过程中的一些经验和心得&#xff0c;希望能为你的项目提供帮助。 1. 蓝牙协议基础 蓝牙协议是无线通信的一种标准&#x…

算法日记 40 day 单调栈

最后两题了&#xff0c;直接上题目。 题目&#xff1a;接雨水 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1…