Spring知识体系

2023-11-18

Spring知识体系

一、基本介绍

1.Spring全家桶:

Spring、SpringMVC、Spring Boot、Spring Cloud

其中Spring是其他的基础。

2.Spring:

出现的目的是为了解决企业级开发的难度。减轻对项目模块之间的管理,类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系。

3.核心技术:

IOC、AOP:实现模块之间,类之间的解耦合。

4.依赖概念:

类A使用了类B属性或方法、称A依赖于B。

二、Spring优点

1.使用Spring的IOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑

2.可以提供众多服务,事务管理,WS等。

3.AOP的很好支持,方便面向切面编程。

4.对主流的框架提供了很好的集成支持,如Hibernate,Struts2,JPA等

5.Spring DI(也即使IOC:反转控制)机制降低了业务对象替换的复杂性。

6.Spring属于低侵入,代码污染极低。

7.Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部

补充:

框架是一个软件,是其他人写好的软件。

1.知道框架能做什么:如mybatis > 访问数据库,对表中的数据实现增删改查。

2.框架的语法格式:框架要完成一个功能,是需要一定步骤支持的。

3.框架的内部实现:框架内部怎么做,原理是什么。(提升)

4.通过学习,可以实现一个框架。(方向)

三、核心功能一:IOC(控制反转)

基于XML的DI:

1、相关概念:

①.IOC:是一个理论,概念,思想。描述的是把对象的创建,赋值,管理工作都交给代码之外的容器去实现。对象的创建是由其他外部资源完成。

②.控制:创建对象,对象的属性赋值,对象之间的关系管理。

③.正转:由开发人员在代码中,使用new构造方法创建对象,开发人员主动管理对象。

④.反转:把原来开发人员的管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理对象,创建对象,给属性赋值。

⑤.容器:可以是一个服务器软件,也可以是一个框架。

⑥.为什么要使用IOC呢:目的是减少对代码的改动,也能实现不同的功能。实现解耦合。

2、IOC的技术实现:

①.DI(Dependency Injection 依赖注入)是IOC的技术实现。

我们只需要在程序中提供要使用的对象的名称,至于对象如何在容器中创建,赋值,查找都有容器在内部实现。

Spring是使用的DI实现IOC的功能,Spring底层创建对象,使用的是反射机制。

②.创建过程:

1.创建Maven
2.导入依赖
3.创建类(接口和他的实现类)就是普通类
4.创建Spring需要使用的配置文件  在文件中声明配置信息。这些类由Spring创建和管理。

代码如下:

<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">

<!--
告诉Spring创建对象
声明bean,就是告诉Spring要创建某个类的对象
id:对象的自定义名称,唯一值。 Spring通过这个名称去找到对象
class:是类的全限定名称(不能是接口,因为Spring是反射机制)
-->
<!-- Spring完成类创建之后,把创建好的对象放进Map中存储起来-->
<!-- 一个bean标签声明一个对象 -->

<bean id="someService" class="com.tjse.service.Impl.SomeServiceImpl"></bean>


</beans>
<!--
    Spring配置文件
    beans是根标签,Spring把java对象称为bean
    spring-beans.xsd是约束文件,和mybatis里面dtd一致。xsd约束效果更强
-->
//      测试类中使用Spring创建bean对象
//      1.创建Spring容器对象,加载Spring配置信息
        ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");
//      2.从容器中获取需要的对象 (需要的某个对象进行强转)
        SomeService someService = (SomeService) ac.getBean("someService");
//      3.正常调用方法
        someService.dosome();

补充:

①.Spring默认创建对象的时间:在创建Spring容器时。

②.使用Spring提供的方法,获取容器中定义的对象数量

​ .getBeanDefinitionCount();

③.获取容器中每个定义对象的名称

​ .getBeanDefinitionNames();

3.设值注入:
Spring配置文件中,给java对象的属性赋值
DI:依赖注入,表示创建对象,给属性赋值

实现语法有两种:
1.基于XML的DI实现
2.基于注解DI实现.

DI的语法分类:
1.set注入:Spring调用类的set方法,在set方法可以实现属性的赋值
2.构造注入:Spring调用类的有参构造方法,创建对象,在构造方法中完成赋值.

注入:就是赋值的意思。

简 单类型:Spring中规定java的基本数据类型和String都是简单类型

简单类型注入如下:

<bean id="" class="">
<property name"属性名" value="属性值">
</bean>

引用类型的set注入如下:

<bean id="" class="">
<property name="属性名称" ref="bean对象id(对象的名称)"></property>
</bean>

补充:这时,我们不用管类是否是自己书写,若想进行赋值操作,那么只需看类里面是否存在set方式(唯一标准)。

构造注入如下:

构造注入使用的是<constructor-arg>标签
其中属性分别为:
name:表示构造方法的形参名
index:表示构造方法的参数位置,参数从左往右的位置是0,1,2的顺序
value:简单类型参数值
ref:引用类型参数值 
4.自动注入:
引用类型的自动注入:Spring框架根据某些规则可以给引用类型进行赋值。(简单类型无效)
不用你再给引用类型赋值。
使用的规则常用byName、byType。
1.byName(按名称注入):java类中引用类型的属性名和Spring容器中(配置文件)
<bean>的ID名称一样,且数据类型是一致的,这样的容器中的bean,Spring能够赋值给引用类型.

语法如下:

<bean id="" class="" autowire="byName">
    简单类型属性赋值
</bean>

代替引用类型,加快开发效率。

2.byType(按类型注入):java类中引用类型的数据类型和Spring容器中(配置文件)
<bean>的class属性是同源关系的,这样的bean能够赋值给引用类型。

同源就是一类意思:
	1.java类中引用的类型的数据类型和bean的class的值是一样的
	2.java类中引用的类型的数据类型和bean的class的值父子类关系的
	3.java类中引用的类型的数据类型和bean的class的值接口和实现类关系的。

语法如下:

<bean id="" class="" autowire="byType">
    简单类型属性赋值
</bean>

注意说明:在byType,在xml配置文件中声明bean只能有一个符合条件的,多余一个是错误的。

5.多配置文件:

优点:

1.每个文件大小比一个文件要小很多,效率高,避免多人操作带来的冲突。

多文件的分配方式:

1.按功能模块,一个模块一个配置文件。

2.按类的功能,数据库相关的配置一个配置文件,做事务的功能一个配置文件,做service功能的一个配置文件等。

<!--   
 Spring-total表示主配置文件:包含其他的配置文件的,主配置文件一般不定义对象的。
 语法:<import resource="其他配置文件的路径"/>
 在包含关系的配置文件中,可以是通配符。(*)
 使用时注意不要写成死循环。(总文件名包含在通配符识别文件中)
 -->
<import resource="classpath:"></import>

基于注解DI:

通过注解完成java对象创建,属性赋值。

1.使用注解的步骤:

①加入maven的依赖Spring-context,在你加入spring-context的同时。简介加入spring-aop的依赖。使用注解必须使用spring-aop依赖。

②在类中加入Spring的注解(多个不同功能的注解)

③在Spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置。

④创建容器,使用类

2.需要学习的注解:

① @Component:组成部分,组件。

类中:

@Component:创建对象的,等同于<bean>的功能
            属性:value就是对象的名称,也就是bean的id值
            value的值是唯一的,创建的对象在整个Spring容器中就一个
@Component(value = "myxxx")
也可以
@Component("myxxx"):省略value
或
@Component :不指定对象名称,有Spring默认提供:类名的首字母小写

配置文件中:

<!-- 声明组件扫描器  component-scan -->
<context:component-scan base-package="类所在的包名"></context:component-scan>

② @Repository:仓库,知识库

用在持久层类上面

放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库数据。

③ @Service

用在业务层类的上面

放在service的实现类上面,创建service对象,service对象是做业务处理的。可以有事务功能的。

④ @Controller

用在控制器上面的

放在控制器(处理器)类的上面,控制器对象,能够接收用户提交的参数,显示请求处理结果。

以上三个注解语法和@Component一样的,都能创建对象,但是三个注解还有额外功能

主要用于给项目对象分层。

⑤ @Value

简单类型的属性赋值

属性: value 是String类型的,表示简单类型的属性值

位置:1.在属性定义的上面,无需set方法,推荐使用。

​ 2.在set方法上面

⑥ @Autowired

引用类型的赋值:自动注入原理,支持byName,byType

1.默认使用byType

位置:在属性定义上面,无需set方法,推荐使用

2.使用byName

需要在@Autowired 下面加入@Qualifier(value = “bean的id”)

练习:使用注解方式 实现创建对象 对属性(包括引用类型)进行赋值

1.遇到问题:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘java.lang.String’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

2.问题分析

可以看到提示显示的是没有找到NoSuchBeanDefinition 原因是springioc容器加载bean默认使用无参构造进行初始化。

而Spring实例化bean有四种方式

1.无参构造方法实例化(Spring默认,常用,需要bean类中存在无参构造方法);

2.静态工厂实例化

3.实例化工厂实例化

4.注解方式实例化+

3.问题解决

加一个默认的构造方法就可以了。

⑦ @Resource

来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值,使用的也是自动注入远,支持byName,byType 默认是byName。

位置:在属性定义的上面,无需set方法 推荐使用。

处理过程:先使用byName,如果失败,则继续使用byType。

两种DI方法区别:

更改代码较多:xml

整体便捷明了:注解

四、核心功能二:AOP(面向切面编程)

​ AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程 序运行过程。 AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB 的动态代理。让开发人员用一种统一的方式,就用动态代理。

​ Aspect:切面。给你的目标类增加的功能, 一般都是非业务方法。

​ Orient :面向

​ Programming:编程

如何理解:

①:需要分析项目功能时,找出切面

②:合理的安排切面的执行时间(在目标方法前,还是目标方法后)

③:合理的安排切面的执行位置。

通过动态代理引入AOP
1.jdk动态代理实现步骤:

①创建目标类,someServiceImpl目标类,给它的dosome,doother增加输出时间,事务

②创建InvocationHandler接口的实现类,在这个类实现给目标方法增加功能。

③使用jdk中 类Proxy,创建代理对象。实现创建对象的能力。

术语:

Aspect:切面。给你的目标类增加的功能, 一般都是非业务方法。常见的切面功能有日志,事务,统计信息,参数检查,权限验证。

JoinPoint:连接点,连接业务方法和切面的 位置,就某类中的业务方法。

Pointcut:切入点,指多个连接点方法的集合。

目标对象:给哪个类的方法增加功能,这个类就是目标对象

Advice:通知,通知表示切面功能执行的时间。

AOP的实现:

aop是一个规范,是动态代理的规范化,一个标准。

aop的技术实现框架:

1.spring:spring的内部实现了aop规范,能做aop的工作。

​ spring主要在事务处理使用aop。项目开发中很少使用aop 比较笨重。

2.aspectJ:一个开源的专门做aop的框架。spring框架集成了aspectJ框架

通过spring就能使用aspectJ的功能。aspectJ框架实现aop两种方式。

一种使用xml的配置文件:配置全局事务。

在项目中实现aop功能,一般都使用注解,aspectj有5个注解。

aspectJ的框架使用:

1.切面的执行时间,这个执行时间在规范中叫做Advice(通知,增强)

在aspectJ框架中使用注解表示的。

@Before

@AfterReturning

@Around

@AfterThrowing

@After

2.表示切面执行的位置,使用的是切入点表达式。

必须写: execution(方法返回值 方法声明(参数))

aspectJ实现aop的基本步骤:

1.新建maven项目

2.加入依赖

​ ①spring依赖

​ ②aspectJ依赖

​ ③junit单元测试

3.创建目标类:接口和实现类 要做的事给类中的方法添加功能

4.创建切面类:普通类

​ ①在类的上面加入@Aspect

​ ②在类中定义方法,方法就是切面要执行的功能代码,在方法的上面加入aspectj的通知注解,例如@Before 还需要指定切入点表达式execution()

5.创建Spring的配置文件:声明对象,要把对象交给容器统一管理。

​ ①声明目标对象

​ ②声明切面类对象

​ ③声明aspectJ框架中的自动代理生成器标签。 它是用来完成代理对象的自动创建功能的。

  1. 创建测试类,从spring容器中获取目标对象(实际上就是代理对象) 通过代理执行方法,实现aop的功能增强。

未完 待后续更新。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring知识体系 的相关文章

  • 如何使用 UnboundID LDAP SDK 获取 LDAP 中的 DN 和用户 ID

    当我唯一的参数是用户 ID 时 我试图获取用户的 DN 可能不止一个 我还使用 UnboundID LDap SDK 如您所见 public String getCustomerAdminDN String uid String resul
  • 如何重定向到WEB-INF文件夹中的JSP

    我有一个带有 NAV 的 jsp 其中还包含 UL 和以下元素 如下面的代码所示
  • JFrame 图标在 Ubuntu 12.04 中不显示

    我使用一些图像图标开发了一个 Swing 应用程序 应用程序 jar 文件在 Windows 中按预期工作 但相同的 jar 文件在 Ubuntu 12 04 操作系统上不显示框架的图像图标 我的示例代码 ImageIcon ImageIc
  • 涉及数学的方法给出与计算器不同的答案

    我是java新手 所以请耐心等待 我试图从比赛总数中获得胜利的百分比 但我正在做的事情还很遥远 我获取百分比的方法如下 public double winPercentage int wins int total return wins t
  • 如何通过双击图标来执行JAVA程序?

    我写了一个java程序 现在我想在没有 IDE Eclipse 等的情况下打开我的控制台 java 应用程序 只需双击桌面上的可执行版本即可 我已将 java 项目导出为 Runnable JAR 文件 但无法打开 当我尝试使用cmd打开应
  • 使用 Windows 锁定屏幕后删除 Kerberos 缓存票证

    无论如何 有没有办法阻止 Kerberos 缓存的票证在 Windows 进入锁定屏幕后被删除 首次登录 Windows 时 klist exe 显示 2 个缓存票证 但是 发生 Windows 锁屏事件后 klist exe 显示 0 个
  • 如何从网上获取源代码?

    我正在尝试从 Web 获取 HTML 源代码 我尝试这样做 u new URL url URLConnection con u openConnection con setRequestProperty User Agent Mozilla
  • 在Java中打印时差最惯用的方法是什么?

    我熟悉以毫秒为单位的打印时间差 long time System currentTimeMillis do something that takes some time long completedIn System currentTime
  • 在同一个容器但不同的耳朵中使用本地EJB

    我正在尝试在同一个 Glassfish 但不同的耳朵中使用本地 EJB 但是Glassfish找不到本地EJB或者无法消费 我读到了这个 根据 JavaEE 教程 Local bean 的客户端 必须在与其访问的企业 bean 相同的 JV
  • Jlist 自定义渲染器

    我正在尝试添加一个我猜你会称其为列表中每个项目的子列表 我构建了一个自定义渲染器 它提供以下输出 正如你所看到的 有些东西不对劲 我没能找到问题的答案 我猜我需要更改面板布局中的某些内容才能获得正确的结果 但不知道是什么 https i s
  • 调用本机方法时返回 java.lang.UnsatisfiedLinkError

    我正在尝试为第三方 DLL 制作 Java 包装器 我创建了自己的 DLL 充当 JNI 和第三方 DLL 之间的中间人 在java中我加载这个DLL很好但是错误java lang UnsatisfiedLinkError sixense
  • 为什么对象可以改变类变量的值?

    由甲骨文提供定义 http docs oracle com javase tutorial java javaOO classvars html 有时 您希望拥有所有对象共有的变量 这是通过 static 修饰符来完成的 声明中带有 sta
  • 使用 testcontainer 作为 Dockerfile 的一部分运行测试

    我的 dockerfile 看起来像这样 FROM maven 3 jdk 11 slim COPY pom xml COPY src src RUN mvn clean install 这意味着构建的一部分是单元测试的执行 一些单元测试使
  • Java 堆分析因 SIGABRT 崩溃

    我正在尝试分析由 C 编写的方法分配并插入的本机内存JVM通过JNI 我安装了 valgrind version valgrind 3 13 0 并尝试使用以下选项运行 JVM valgrind tool massif massif out
  • 在硬件级别模拟按键 - Windows

    我正在寻找一种语言或库 使我能够在最大可能的水平上模拟击键 而无需实际按下按键 我对击键级别的具体衡量标准是 当我的计算机已经运行按键侦听器 例如鼠标键和粘滞键 时 它是否会产生与物理按键相同的输出 我尝试过很多击键模拟的方法 java A
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • 在 Android 版 ORMLite 中加入类会引发 SQL 异常:找不到外部类,反之亦然

    我正在尝试使用 QueryBuilder 为两个不同的类创建一个联接查询 一个Product类和一个Coupon类 引用 Product 属性 storeId public class Coupon DatabaseField column
  • Spring MVC 和复选框

    我正在使用 Spring MVC 3 0 并且不能完全看到这个问题的所有部分 我的控制器将生成一个域对象列表 假设有一个简单的 User 对象 具有firstName lastName age 和role 属性 我想在表中输出该用户列表 每
  • java银行程序帐户ID不上去?

    每次创建银行帐户时 帐户 ID 都应增加 1 但每次我尝试提取 Id 时 我只会得到帐户 ID 为 0 任何建议 因为我完全按照我学习的书中的方式进行操作而且它仍然没有更新 帐户构造函数 public class BankAccount p
  • 将菜单添加到空活动

    我在 Android Studio 中制作了一个 Android 应用程序 并想在其上创建一个选项菜单 我将其创建为一个空活动 现在意识到我最好创建一个空白活动来获取选项菜单 无论如何 是否可以在空活动中创建选项菜单 如果有人能给我指出一个

随机推荐

  • c++ 模板的具体化与实例化

    函数模板是C 新增的一种性质 它允许只定义一次函数的实现 即可使用不同类型的参数来调用该函数 这样做可以减小代码的书写的复杂度 同时也便于修改 注 使用模板函数并不会减少最终可执行程序的大小 因为在调用模板函数时 编译器都根据调用时的参数类
  • Unity3d 简单的按照路径移动物体!

    在TORQUE引擎中 我们只要设置几个点 然后物体会按照这几个点顺序移动 Unity3d也可以的 现在介绍一个很简单的按照路径移动的方法 目标是让蓝色方块沿着紫色方块组成的路径移动 设计思想就是让蓝色方块移动第一个 然后继续移动到第二个 然
  • 室内探索无人机,解决复杂环境下的任务挑战!

    前言 室内探索无人机是一种专为在室内环境中进行任务的无人机系统 相比传统的人员部署 室内探索无人机具有更高的灵活性和机动性 能够在复杂的室内环境中执行任务 用于未知环境的探索和特定目标的搜索 为完成无人机室内搜索与识别等复杂任务 阿木实验室
  • Ubuntu18环境下 python 多进程与多线程测试

    Ubuntu18环境下 python 多进程与多线程测试 测试说明 单一线程单一进程测试函数 多线程下测试函数 多进程下测试函数 主函数与测试结果 测试说明 测试的对象为多次求平方的程序 def task powers limit int
  • 鸿蒙内核阅读笔记-时间管理(los_sys)

    简介 近期在阅读鸿蒙liteOS a 由于是初次探索内核的奥秘 将一些阅读的心得进行分享 希望能在作为笔记的同时 也能帮助更多人学习 感谢图灵大佬的注释项目 使我能够更加快速的理解 https weharmony github io 核心模
  • C语言用循环编写简单菜单程序

    C语言用循环编写简单菜单程序 源码如下 include
  • MyBatis架构与原理深入解析

    点击上方 芋道源码 选择 设为星标 管她前浪 还是后浪 能浪的浪 才是好浪 每天 8 55 更新文章 每天掉亿点点头发 源码精品专栏 原创 Java 2020 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络
  • 汽车信息安全标准ISO/SAE21434与UN/WP.29阅读总结

    1 序言 伴随着汽车与外界的交互手段不断丰富 车联网相关设备 系统间的数据交互更加频繁 万物互联下的网络攻击也逐渐渗透延伸到车联网的领域 这给汽车行业带来了新的 专属挑战 我这几天简要阅读了汽车信息安全领域的几个重要的国际规范 本文就简要讨
  • 光分配网(ODN)一级分光和二级分光的区别及应用场景

    光分配网 ODN 的分光方式主要有两种 一级分光和二级分光 如图1所示 受PON设备光功率预算及带宽的限制 当前 ODN的总分路比一般为1 64 图1 ODN的一级分光和二级分光 采用一级分光时 分路器一般设置在配线光交处 采用二级分光时
  • 什么是新生代的复制算法

    https blog csdn net ooppookid article details 51523701 1 什么是新生代的复制算法 了解堆内存看这里 java堆内存是什么样的 了解java垃圾回收看这里 java垃圾回收机制是什么 所
  • 图像拼接算法及实现_浅谈图像处理算法的实现途径(CPU/FPGA/ASIC)

    人们对图像质量要求的不断提升 直接推动着图像算法的不断向前发展 那么到今天为止 常用的图像处理算法是怎么实现的呢 今天我们来谈一谈 图像处理算法的实现一般有两种途径 软件或者硬件 软件 VS 硬件 软件实现方式 成本低 迭代快 且随着现在各
  • c++调用sqlite3(带加解密)

    StringConvert见https blog csdn net wxd090108 article details 84190762 第三方文件 下载地址 https sourceforge net projects wxcode fi
  • 第六题 整除排序

    题目描述 有一个序列 序列的第一个数是n 后面的每个数是前一个数整除2 请输出这个序列中的值为正数 的项 输入格式 输入一行包括一个整数n 输出格式 输出一行 包括多个整数 相邻的整数之间用一个空格分开 表示答案 测评用例规模和标准 对于8
  • 原理图库元件符号之二极管模型的创建

    今天我们来绘制一个二极管的模型 效果图如下 Step 01 首先画两个引脚 并把Name属性隐藏 Step 02 使用多边形命令 绘制二极管的本体 Step 03 修改多边形属性 多边形线宽改为smallest 然后填充为蓝色 效果图如下
  • Vue中export const 和 export default的区别

    export const 一个文件中可以有好多个 名字叫命名导出 export default 一个文件中只能有一个 名字叫默认导出 代码举例 详见资料链接
  • kong配置好跨域组件后,仍不能跨域,

    路由配置加上OPTIONS
  • python写入txt不覆盖_python不能覆盖文件内容如何解决

    python不能覆盖文件内容的解决方法 使用 with open f w as file 命令即可覆盖文件内容 w 代表每次运行都覆盖文件内容 python不能覆盖文件内容有可能是因为文件的打开方式为追加写方式 更改文件打开方式即可实现再次
  • Linux内存分析free与cache清理

    1 free命令 Linux中查看内存的命令为free 命令如下 free h total used free shared buff cache available Mem 62G 4 9G 627M 520K 57G 57G Swap
  • 面试顺序问题:用数学建模优化生产与服务运作中的管理问题

    例题 有 4 名同学到一家公司参加三个阶段的面试 公司要求每个同学都必须首先 找公司秘书初试 然后到部门主管处复试 最后到经理处参加面试 并且不允许插队 即 在任何一个阶段 4 名同学的顺序是一样的 由于 4 名同学的专业背景不同 所以每人
  • Spring知识体系

    Spring知识体系 一 基本介绍 1 Spring全家桶 Spring SpringMVC Spring Boot Spring Cloud 其中Spring是其他的基础 2 Spring 出现的目的是为了解决企业级开发的难度 减轻对项目