Spring IoCDI(下)—DI的尾声
我们之前学习了控制反转IoC,接下来就开始学习依赖注入DI的细节。
依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。我们使用 @Autowired 注解,完成依赖注入的操作。简单来说,就是把对象取出来,放到某个类的属性中。由此,依赖注入也被称之为 “对象注入”、“属性装配”,具体含义需要结合文章的上下文来理解。
关于依赖注入,Spring也给我们提供了三种方式:
1、属性注入(Field Injection)
2、构造方法注入(Construct Injection)
3、Setter 注入(Setter Injection)
1. 属性注入
属性注入是使用 @Autowired 实现的,将UserService 类注入到UserController类中,UserService 类代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.stereotype.Service;@Service
public class UserService {public void doService() {System.out.println("do Service...");}
}
UserController类的实现代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {//注入方法1:属性注入@Autowiredprivate UserService userService;public void sayHi() {userService.doService();System.out.println("hi, UserController");}
}
启动类获取到UserController的doService方法,代码如下:
package com.example.zxslzw2014_8_11;import com.example.zxslzw2014_8_11.controller.UserController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
public class Zxslzw2014811Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(Zxslzw2014811Application.class, args);//从Spring上下文中获取对象UserController1 userController1 = (UserController1) context.getBean("userController1");//使用对象userController1.sayHi();}
}
运行结果如下:

去掉注解@Autowired,运行结果如下:

报错信息显示空指针异常,没办法调用doService() 方法,因为userServer为空。没有加@Autowired注解,即没有注入依赖,Spring拿不到这个属性,就不会给它初始化了,那么它肯定就是一个空指针了。
2. 构造方法注入
构造方法注入就是在类的构造方法中实现注入,代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {private UserService userService;//注入方法2:构造方法注入@Autowiredpublic UserController1(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("hi, UserController");}
}
或
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {private UserService userService;//注入方法2:构造方法注入public UserController1(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("hi, UserController");}
}
运行结果如下:

如果类只有一个构造方法,那么@Autowired注解可以省略;但如果类有多个构造方法,那么就需要添加上@Autowired来明确指定要使用哪个构造方法了。下面给userController1增加一个无参构造,代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {//注入方法1:属性注入
// @Autowiredprivate UserService userService;//注入方法2:构造方法注入
// @Autowiredpublic UserController1(){}public UserController1(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("hi, UserController");}
}
运行结果如下:

报错显示,空指针异常,我们的类交给Spring管理,Spring内部会给我们自动创建对象,但是是通过构造函数创建的,上图我们写了两个构造函数,如果不加@Autowired注解,Spring默认使用无参构造函数,如此就不能成功创建对象了,所以这个userService也自然是空指针了。
现在代码改一下,把无参构造函数注释掉,更新构造函数,代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {//注入方法1:属性注入
// @Autowiredprivate UserService userService;private UserComponent userComponent;//注入方法2:构造方法注入public UserController1(UserService userService) {this.userService = userService;}public UserController1(UserService userService, UserComponent userComponent) {this.userService = userService;this.userComponent = userComponent;}public void doController() {userService.doService();userComponent.doComponent();System.out.println("hi, UserController");}
}
运行结果如下:

报错显示,没有找到默认的构造方法,因为这里出现了两个构造方法,Spring不知道该用哪个,现在给第二个构造方法加上@Autowired注解,表示让Spring使用被注解的构造方法,运行结果如下:

综上:
1、只有一个构造函数的情况,可以不加@Autowired2、如果有多个构造函数,需要指定默认的构造函数(通过@Autowired指定,如果未指定,默认使用无参的构造函数)。
构造规范:如果添加构造函数,把无参构造函数显示添加(也就是把构造函数写下来,再给注释掉)
3. Setter注入
Setter注入和属性的Setter方法实现类似,只不过在set方法的时候需要加上@Autowired注解,代码如下:
package com.example.zxslzw2014_8_11;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController1 {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("hi, UserController");}
}
结果如下:
同时我们把@Autowired注解去掉的话,又会出现空指针异常,原因和属性注入把@Autowired的情况一样,就是spring优先使用空参构造,结果空参构造的对象不能匹配到我们所调用的方法。
4. 三种注入的优缺点分析
4.1 属性注入
优点:
1、简洁、使用方便。
缺点:
1、只能用于IoC容器,如果非IoC容器则不可用,并且只有在使用的时候才会回出现NPE(空指针异常)。reason:如下图,可以看到,它的来源是Spring的,那么就只能用于IoC容器了。

2、不能注入一个final修饰的属性。
reason: final修饰的属性有个特点,必须初始化,如果我们给属性加上final,会有两种解决方案:
方案1、提供构造函数,如图:
如果加上构造方法,我们的属性注入就变成了构造方法注入。
方案二: 给它初始化,new 一个对象:
如此我们的代码就只能自己管理了,Spring不会帮我们管理,这不是ioc的思想;
4.2 构造方法注入
(Spring4.X推荐)
SpringBoot和Spring的版本号对应:
Spring Boot3.X -> Spring 6
Spring Boot2.X -> Spring 4
优点:
1、可以注入final修饰的属性。final修饰的属性要初始化,构造方法会进行初始化,复合它的要求。
2、注入的对象不会被修改。
因为构造方法在这个类创建的时候就会给它进行赋值了,不会再对它进行修改
3、依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法。
在类加载的这个阶段,就会执行构造方法了,把依赖对象给初始化完成。
4、通用性好,构造方法是JDK支持的,所以更换任何框架,它都是适用的。
因构造方法是JDK支持的,不再Spring框架也能正常的使用
缺点:
注入多个对象时,代码会比较繁琐。
4.3 Setter注入
(Spring3.X推荐)
优点:
方便在类实例之后,重新对该对象进行配置或注入。因为Setter方法是可以被其他地方调用的,所以即使类已经被实例化了,也可以重新对该对象进行配置或注入。
缺点:
1、不能注入一个final修饰的属性。因为可能会被多次修改,所以不能使用final修饰。
2、注入对象可能会被改变,因为Setter方法可能会被多次调用,就有被修改的风险。
Setter方法当然能被修改了,这即使它的优点,也是它的缺点。
4.4 Autowired查找依赖顺序
1、根据名称和类型去查。
2、如果根据名称查不到,就会根据类型去查。
根据名称查不到了,去查找类型,这时如果类型匹配多个,就会报错。
5. @Autowired存在问题
当同一类型存在多个bean时,使用@Autowired会存在问题。代码如下:
@Component
public class BeanConfig {@Beanpublic UserInfo userInfo1() {UserInfo user = new UserInfo();user.setId(6);user.setName("shenmengyao");user.setAge(18);return user;}@Beanpublic UserInfo userInfo2() {UserInfo user = new UserInfo();user.setId(7);user.setName("yuanyiqi");user.setAge(19);return user;}
}
此时我们在UserController1类里面注入UserInfo类,代码如下:(下面这几个的注入方式都是错误的)
5.1 引入Autowired的错误代码:
5.1.1 属性注入:

尝试运行出现如下结果:

5.1.2 构造方法注入

5.1.3 Setter方法注入

5.1.4 启动类代码:

上面这三种方式注入都会出问题,启动程序后,而报错信息也都是一样的,如上图所示:

程序还没启动就失败了,可以看出来,Spring的依赖注入是在项目启动前就开始注入的了。
上面报错提示:UserController1类需要一个bean,但是有两个,下面也打印出是哪两个bean了,Action介绍的就是解决方案。报错日志非常详细。
报错信息说UserController1类找不到依赖注入的是哪一个,因为有多个方法被@bean注释,而依赖注入时,三个方法的属性名都是userInfo,系统先根据userInfo名称查找,但BeanConfig类没有这个方法名,那就只能去根据类名找了,但有2个bean,Spring就不知道要找那个了,并不是@bean注释下的方法名(userInfo1 / userInfo2),Spring并不知道该注入哪个依赖,所以报错了。
在项目启动失败,可以把Filed看为属性,如上图:这个是使用属性注入的,会有Field;
构造方法和Setter注入都是第一张报错图,但就不是Field了,而是Parameter,但其实三种注入的报错原因都是一样的。
解决方案:使用属性注入时,就把属性名改成bean修饰的其中之一的方法名就好了;使用@Parimary注解;使用@Qualifier注解;使用@Resource注解。
5.2 解决方案
5.2.1 解决方案一:根据名称去查
属性名改成bean修饰的其中之一的方法名
1、属性注入:

2、构造方法注入:

3、Setter方法注入:

上面三种执行结果都一样,这里虽然注入了依赖,但没有用这些依赖;
5.2.1 解决方案二:
给想要拿到的对象加上@Primary注解
这个可以理解为依赖注入后,有多个依赖的方法,但默认使用加了@Primary的方法,代码如下:
1、UserController类

2、BeanConfig类:

代码运行结果:

其他注入的方式,使用@Primary注解用法也一样,把想要拿到的对象加上@Primary注解就好了。
5.2.3 解决方案三:
加@Qualifier注解,指定引入的依赖对象
UserController类:

BeanConfig类和启动类与最初的代码一样,不用变。代码最终能够成功运行,结果和之前类似;
5.2.4 解决方案四:加@Resource注解
这里和上面的三方案代码改变的只有UserController类,其他都不变,UserController类的代码如下:
@Controller
public class UserController {@Resource(name = "userInfo1")@Autowiredprivate UserInfo userInfo;public void sayHi() {System.out.println(userInfo.toString());System.out.println("hello, controller");}
}
运行结果如下:

这个注解不是Spring的,而是JDK本身自带的,JDK早期也有这样的注解,所以Spring不推荐使用这个注解,因为不是自己开发的,如果出现啥问题,不好处理,是有着不可控因素的原因;还有使用自家的东西也肯定会更放心一些。
5.3 @Autowired 与 @Resource 的区别
1、@Autowired 是 Spring框架提供的注解,而@Resource是JDK提供的注解。
2、@Autowired默认是按照类型注入,而@Resource是按照名称注入。相比于 @Autowired 来说,@Resource 支持更多的参数设置;例如 name 设置,根据名称获取 Bean。
6. Spring IoC&DI 的总结
1、Spring,Spring Boot 和 Spring MVC的关系以及区别
(1)、Spring
简单来说,Spring是一个开发应用框架,其目的是用于简化企业级应用程序开发。Spring的主要功能:管理对象,以及对象之间的依赖关系,面向切面编程、数据库事务管理、数据访问、web框架支撑等等。
Spring具备高度可开发性,并不强制依赖Spring,开发者可以自由选择Spring的部分或者全部,Spring可以无缝继承第三方框架,比如数据访问框架(Hibernate、JPA等等),web框架(如:Struts、JSF等等)。
(2)、Spring MVC
Spring MVC是Spring的一个子框架,Spring诞生之后,大家按照MVC模式设计了一个MVC框架(用Spring解耦),主要用于开发WEB应用和网络接口,所以Spring MVC是一个Web框架。Spring MVC是基于Spring进行开发的,可以让我们更简洁的进行Web层开发,支持灵活的URL到页面控制器的映射,提供了强大的约定大于配置的契约式编程支持,非常容易与其他视图框架集成,如 Velocity、FreeMarker等等。
(3)、Spring Boot
Spring Boot 是对Spring的一个封装,为了简化Spring一样的开发而出现的,使用Spring Boot 可以更加快速的搭建框架,降低开发成本,让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现。Spring Boot可以快速的集成其他框架进来。想使用Spring Boot开发Web项目,只需要引入Spring MVC框架即可,Web开发的工作是Spring MVC完成的,而不是Spring Boot,想完成数据访问,只需要引入Mybatis框架即可。
Spring Boot只是辅助简化项目开发的,让开发变得更加简单,甚至不需要额外的web服务器,直接生成jar包执行即可。
(4)、总结
Spring MVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包。之前写的图书管理系统代码中,整体框架是通过SpringBoot搭建的IoC,DI功能是Spring提供的,而Web相关功能是Spring MVC提供的。
因为这三个专注的领域不同,所以解决的问题也不一样,总的来说,Spring就像一个大家族,有众多衍生产品,但它们的基础都是Spring;
2、bean的命名
(1)、五大注解存储的bean
1、类名前面两位字母均为大写,则bean名称为该类名本身(特殊情况)。2、不是上面的特殊情况,其他的类名,首字母小写,驼峰形式命名。
3、通过 value 属性设置bean名 ,例如:@Controller (value = "user")。
(2)、@Bean注解存储的bean
1、bean名称为方法名。
2、通过name属性设置bean名,例如:@Bean (name = {"u1", "user1"})。
ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!
本文的封面来自:bilibili苏杉杉的pv,侵权删 url:https://www.bilibili.com/video/BV1vo4y167eh/?spm_id_from=333.999.0.0&vd_source=866da5be2ef0ddd213b053523da53138
————————————————
电子签名:上嘉路
相关文章:
Spring IoCDI(下)—DI的尾声
我们之前学习了控制反转IoC,接下来就开始学习依赖注入DI的细节。 依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。我们使用 Autowired 注解,完成依赖注入的操作。简单来说…...
仕考网:考外省公务员可以调回本地吗?
一般情况下,公务员岗位是固定不可随意更换的,因为每个职位都对应特定的职责和要求。一旦考到外地的岗位,想要调回本地几乎是不可能的。因为这样的操作可能导致职位空缺,进而需要通过公共招聘流程来填补,而不是简单地从…...
《工厂模式在软件开发中的深度剖析与应用》
工厂模式 在软件开发的领域中,设计模式充当着解决常见问题的高效且可复用的策略角色。其中,工厂模式作为创建对象的重要设计模式,具有不可小觑的应用价值。接下来,我们将深入探讨简单工厂模式、工厂方法模式和抽象工厂模式。 一…...
双向通信之Websocket
介绍 Websocket是一种在单个TCP连接上进行全双工通信的协议。与传统的HTTP协议不同,websocket允许客户端与服务器之间的双向通信,可以在同一条连接上进行多次消息的快速传递。我之前在做一个线上刷题网站的时候,需要设计一个社区讨论模块&am…...
git学习使用碰到的问题1
本来在B站上看到的关于stash的使用时视频末尾讲到git stash drop 编号 会删除暂存记录 确实也是这么回事,但是末尾说到git stash pop 编号时up主说在恢复工作进度的时候我们可以直接删除掉这个工作记录可以直接使用 git stash pop stash{0} 使用完以后却出现了如上图…...
JavaScript初级——Math
一、Math 和其他的对象不同,它不是一个构造函数。它属于一个工具类,不用创建对象,里边封装了数学运算相关的属性和方法。 比如: Math.PI 表示圆周率。 二、Math.abs() —— 可以用来计算一个数的绝对值。 三…...
ffmpeg的基础命令
文章目录 ffmpeg/ffplay/ffprobe区别ffmpeg 的作用ffplay的作用ffprobe的作用 ffmpeg使用概述功能概述转码过程简单使用FFMPEG -i常用的 -i例子 ff***工具之间共享的选项ffmpeg主要选项ffmpeg提取音视频数据ffmpeg命令修改原有的视频格式ffmpeg命令裁剪和合并视频拼接视频的方式…...
二建机电工程实务试题内附答案
1.下列有色金属材料中,不属于铜合金的是()。 A.紫铜 B.青铜 C.黄铜 D.白铜【答案】A 2.用于完成介质间热量交换的换热设备是()。 A.分离器 B.反应器 C.冷凝器 D.分解锅【答案】C 3.工程测量的核心是()。 A.测量精度 B.设计要求 C.减少误差累积 D.检核【答案】D 4.吊…...
Redis的热key以及Big(大)key是什么?如何解决Redis的热key以及Big(大)key问题?
一、先讲讲什么是redis的热key问题 在Redis中,我们把访问频率高的Key,称为热Key。比如突然有几十万的请求去访问redis中某个特定的Key,那么这样会造成redis服务器短时间流量过于集中,很可能导致redis的服务器宕机。那么接下来对这…...
django学习入门系列之第九点《MySQL命令介绍一》
文章目录 MySQL命令数据库的管理(文件夹)查看现在已有的数据库(文件夹)创建数据库(文件夹)删除数据库(文件夹)进入数据库(文件夹)查看文件夹下所有的数据表&a…...
Mysql面试一
目录 一、事务的四大特性(ACID): 脏读 不可重复读 幻读 隔离性与隔离级别 数据库的三大范式 第一范式。确保数据表中的每个字段都是不可分割的最小单位,即原子性。这意味着表中的每一列都应代表一个独立的数据单元ÿ…...
模型优化之剪枝
文章目录 什么是神经网络剪枝剪枝的好处不同粒度的剪枝剪枝的分类非结构化剪枝结构化剪枝 哪些层的参数更容易被剪掉剪枝效果 什么是神经网络剪枝 神经网络剪枝 在训练期间删除连接密集张量将变得稀疏(用零填充)可以通过结构化块( n m nm nm&…...
JVM的组成
JVM 运行在操作系统之上 java二进制字节码文件的运行环境 JVM的组成部分 java代码在编写完成后编译成字节码文件通过类加载器 来到运行数据区,主要作用是加载字节码到内存 包含 方法区/元空间 堆 程序计数器,虚拟机栈,本地方法栈等等 随后来到执行引擎,主要作用是翻译字…...
快速上手 iOS Protocol Buffer
快速上手 iOS Protocol Buffer | 来自缤纷多彩的灰 本文主要介绍在 iOS 开发中如何快速上手使用 Protobuf。更多关于 Protobuf 的介绍和相关的功能 api,读者可自行查阅官网。 Protocol Buffer(简称 Protobuf)是一种由Google开发的语言中立、…...
每天一个数据分析题(四百八十)- 线性回归建模
关于线性回归建模,线性回归模型假设说法不正确的是? A. 因变量和自变量要有因果关系 B. 残差均值为0 C. 残差服从正态分布 D. 自变量不存在共线性 数据分析认证考试介绍:点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专…...
电动汽车和混动汽车DC-DC转换器的创新设计与测试方法
汽车 DC-DC 转换器市场规模将达到187亿美元,年复合增长率为10%。 DC-DC 转换器是汽车的重要组成部分,它可以通过电压转换为各种车载系统供电,例如日益复杂的车载信息娱乐系统、使用驾驶辅助系统(ADAS)实现的增强安全功…...
OriginPro快速上手指南:数据可视化与分析的利器
目录 OriginLab - Origin and OriginPro - Data Analysis and Graphing Softwarehttps://www.originlab.com/编辑 一、安装与界面概览 安装 界面概览 二、基础操作 数据输入 创建图表 三、高级功能 数据分析 自动化与脚本 Origin 提供了几个小工具 四、技巧与提示…...
缓存学习
缓存基本概念 概念 对于缓存,最普遍的理解是能让打开某些页面速度更快的工具。从技术角度来看,其本质上是因为缓存是基于内存建立的,而内存的读写速度相比之于硬盘快了xx倍,因此用内存来代替硬盘作为读写的介质当然能大大提高访…...
亚世光电:消费电子年度表演
机圈风云再起,消费电子乘风而起? 今天我们来聊——亚世光电 最近,华为mate60突然降价,被大家怀疑是为新品上市做准备,算算时间,下半年的消费电子大战也即将拉开帷幕,而亚世光电所在的光电显示领…...
AI 工程应用 建筑表面检测及修复
文章目录 1 项目概述(必写):2 技术方案与实施步骤2.1 模型选择(必写):2.2 数据的构建:2.3 功能整合(进阶): 3 实施步骤:3.1 环境搭建(…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...


