框架基础
Maven基础
-
Maven概述
Maven是为Java项目提供项目构建和依赖管理的工具
-
Maven三大功能
- 项目构建
构建:是一个将代码从开发阶段到生产阶段的一个过程:清理,编译,测试,打包,安装,部署等
- 依赖管理
Jar包下载,Jar包依赖,jar包冲突
- 契约编程
约定大于配置,配置大于编码
注意:Maven连接远程仓库是需要联网的,如果没有网络那么会构建失败
- Maven仓库
所谓仓库就是用来存放Jar包和插件的地方,在Maven中仓库又分为三种:
-
本地仓库
-
远程仓库
- 中央仓库
中央仓库依赖搜索地址,**建议收藏**:https://mvnrepository.com/
- 私服仓库
注意:私服仓库搭建技术:Nexus
- Maven配置
第一步:创建本地仓库文件夹
第二步:修改settings.xml配置文件中的本地仓库地址
第三步:配置阿里云镜像
第四步:配置JDK版本
注意:记得保存配置
-
Maven坐标
Maven中的坐标是项目的唯一标识,通过该坐标可以确定项目Jar包在仓库中的位置,也可以通过坐标来引入项目中所需要的三方依赖
Maven坐标主要组成
- groupId:当前Maven项目隶属于组织名称,通常都是公司域名反写,例如:cn.itsource
- artifactId:项目或者是项目中的一个模块的名称
- version:当前Maven项目版本号,根据需求进行设定
- SNAPSHOT:快照版本,正在迭代过程中,不稳定的版本
- RELEASE:释放,表示正式版本,稳定版本
注意:当我们需要某一个jar包时,可以通过坐标本地仓库的jar包或依赖包
当然:我们的项目也可以安装到本地仓库,执行install命令将项目打成Jar包放在本地仓库中
<parent> <groupId>cn.zhj</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> </parent>
-
Maven命令
**mvn compile:**编译 - 将java源文件.java 编译成 字节码文件.class
**mvn clean:**清理 - 将编译好的字节码文件删除掉
**mvn clean compile:**清理+编译
**mvn test:**测试 - 运行测试代码,测试代码编译在target的test-classes中
注意:src/test/java中的所有测试类的所有方法都会自动运行,但是测试类的类名有要求:TestXxx 或 XxxTest
**mvn package:**打包【.class字节码文件】
**mvn source:jar:**打源码包【.java文件】
**mvn install:**安装 - 将项目打包然后将jar包安装到本地仓库中
**mvn package -Dmaven.test.skip=true:**打包的时候跳过测试类
注意:测试的时候看下目录结构的变化和maven仓库目录的变化
-
搜索并下载依赖
第一步:中央仓库依赖搜索地址:https://mvnrepository.com/
第二步:将搜索到的依赖导入拷贝到pom.xml中,然后点击刷新,点击刷新时如果本地仓库有当前版本的依赖就不会去下载,直接引用本地仓库的依赖。如果没有就会去远程仓库下载,下载到本地再引用
注意:如果本地仓库有,可以直接提示直接引入
-
IDEA执行Maven命令
在IDEA中执行Maven命令非常简单,只需要点击右侧Maven按钮,然后在工程的生命周期中双击想要执行的命令即可
-
查看工程依赖(略)
-
依赖传递
在Maven中依赖是具有传递性的,例如我们刚才项目中只引入了Junit依赖,但是我们也间接依赖了Junit的其他依赖。在Maven项目中依赖分为直接依赖和间接依赖:
-
直接依赖:Junit就是工程的直接依赖
-
间接依赖:hamcrest-core就是工程的间接依赖
-
-
依赖排除
Maven具有依赖的传递性对我们来说是非常大的一个好处,因为这样就避免我们需要去自己引入间接依赖。但是有时候我们在引入多个依赖时,简介依赖的版本不一致会导致依赖冲突,那么此时我们就需要阻断依赖。以Junit为例,阻断间接依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
<!--排除依赖标签,可以写多个-->
<exclusions>
<!--排除依赖标签,写具体要排除那个依赖,只需要写GA坐标即可-->
<exclusion>
<!--要排除依赖的G坐标-->
<groupId>org.hamcrest</groupId>
<!--要排除依赖的A坐标-->
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
- 依赖范围
在Maven中依赖是具有作用范围的,默认情况下依赖的Jar包在任何地方都可以使用,我们可以通过…进行依赖作用范围的指定:
- 主程序范围有效:main文件夹范围内
- 测试程序范围有效:test文件夹范围内
- 是否参与打包运行:package指令范围内
scope取值
scope值 | 主程序main | 测试程序test | 打包/运行 |
---|---|---|---|
compile–默认 | Y | Y | Y |
test | N | Y | N |
provided | Y | Y | N |
runtime | - | Y | Y |
-
清理Maven仓库
初始情况下,我们的本地仓库是没有任何Jar包的,第一次会联网进行下载,可能由于网络的原因,Jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾
注意:如果依赖下载失败,Maven识别到以lastUpdated结尾的文件后就不会再重新帮你下载,需要你删除这些以lastUpdated结尾的文件,然后Maven才会再次自动下载这些Jar包,以后实际开发中如果项目引入了某Jar包刷新后依赖依然报错,那么就需要检查一下此Jar包是否下载成功
解决方案:有时下载依赖有可能批量下载失败,那么此时我们手动去挨着找就非常麻烦,那么我们可以定义一个脚本文件,双击即可全部清除
第一步:在桌面创建一个del_lastUpdated.bat文件,创建文本改后缀即可
第二步:右键编辑bat文件,拷贝以下命令并修改本地仓库文件夹绝对地址
set REPOSITORY_PATH=本地仓库文件夹绝对地址 rem 正在搜索... del /s /q %REPOSITORY_PATH%\*.lastUpdated rem 搜索完毕 pause
第三步:双击执行脚本,即可清除本地仓库下所有lastUpdated文件
Maven高级
继承
在Java中有继承的概念,就是子类继承父类的所有方法和属性。在Maven中同样有继承的概念并且与Java一致都是单继承,本质上Maven的继承就是pom.xml配置的继承
- A工程继承了B工程,那么A工程就继承了B工程的pom.xml所有配置
- Maven继承的层级是没有限制的,大型互联网项目中层级会非常多,我们只需要按照规则去梳理层级即可
-
为什么需要继承
原因一:真实开发中,依赖动则几十上百个依赖,那么这些依赖的版本管理是非常复杂的,为了方便版本管理,那么可以在父工程中统一管理版本信息。子工程直接使用对应版本即可,SpringBoot框架就是使用了Maven继承手段进行开发简化
原因二:真实开发中,一个项目会有很多个子工程,这些子工程都有自己的依赖,那么肯定会有一些重复的依赖,为了减少子工程重复导入依赖坐标信息,可以放在父工程中进行依赖抽取,子工程通过继承的方式进行依赖的引入
-
搭建Maven继承工程
第一步:创建一个Maven工程
第二步
- 删除父工程下的src文件夹,因为父工程只负责管理pom.xml,不负责编写代码,所以不需要src文件
- 修改打包方式为pom,只有打包方式为pom的工程,才能管理其他Maven工程
第三步:创建子工程/Maven模块
-
父子工程解析
- 子工程创建好之后,会自动生成parent标签,指向父工程的GAV坐标
- 子工程是不需要写GV坐标的,因为继承自父工程,子工程只需要提供A坐标即可
- 父工程中有子工程后会自动生成modules标签,代表聚合配置,后续会进行讲解
-
父工程管理依赖
第一步:父工程管理依赖
- dependencyManagement:此标签用于在父工程中管理依赖,但是不负责引入此依赖到工程中,子工程需要使用什么依赖还是需要在自己的子工程中手动引入,只是不需要引入版本,版本来自父工程
第二步:子工程引入依赖
-
配置自定义属性
父工程在真实开发中会管理众多的依赖,那么这些依赖的版本号如果都写在各自的GAV坐标中其实管理起来也颇为复杂,所以我们可以自定义属性进行管理
- properties:此标签是配置标签,我们可以在标签内自定义标签来定义属性值,此属性值可以被引用
- itsource.junit.version:此标签是自定义的,标签名称就是属性引用名称,标签的值就是版本值
- ${}:通过此方式可以引入自定义属性,大括号中的值就是自定义标签的值
- properties:此标签是配置标签,我们可以在标签内自定义标签来定义属性值,此属性值可以被引用
项目结构:
实例代码:
<!-- parent的pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zhj</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>son1</module>
<module>son2</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dom4j-version>1.1</dom4j-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>${dom4j-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<!-- <scope>test</scope>-->
</dependency>
</dependencies>
</project>
<!-- son1的pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.zhj</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>son1</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
</dependencies>
</project>
<!-- son2的pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.zhj</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>son2</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
</dependencies>
</project>
聚合
-
什么是聚合
在父pom.xml中的modules标签就是聚合标签,他表示了此工程由哪些模块组成,modules下的module也代表了此父工程管理了哪些子模块
-
聚合的好处
好处一:如果没有聚合,那么我们例如在执行mvn install命令时,Maven会要求有父工程时先安装父工程,有依赖工程时先安装依赖工程,那么我们自己来考虑这些规则就非常麻烦,我们可以直接对父工程执行mvn install,那么整个工程就自动打包好了
好处二:配置聚合之后,各个子模块在父工程中展示一个列表,可以快速让我们知道整个项目的继承结构
MAVEN扩展知识
1. IDEA的目录结构
Maven项目结构:
.idea目录 - idea中项目配置文件,如果删除了项目崩溃
src - 项目开发目录
target - maven项目编译目录
.gitignore - git项目版本控制器上传到码云gitee,githup上时忽略文件
pom.xml - maven项目核心配置文件
设置如何不显示再IDEA中:
settings - Editor - File Types - Ignored Files and Folders
Spring概述
Spring发展史
-
Spring时代
Spring框架于2003年首次发布,由Rod Johnson创立,它的目标是简化Java开发,并提供一种更灵活、高效的替代方案
Spring框架引入了依赖注入(DI)和面向切面编程(AOP)等新概念,以减少组件之间的耦合度、提高代码的可维护性和可测试性
Spring通过IoC容器(控制反转容器)来管理对象之间的依赖关系,并提供了许多其他功能模块,如数据访问、事务管理、安全性等,使开发者能够更专注于业务逻辑的实现
**小结:**Spring提供IOC控制反转 - 管理对象,提供了AOP - 抽取公共业务
-
SpringBoot时代
随着时间的推移,Spring框架变得越来越强大和复杂,为了简化Spring应用程序的开发和部署,SpringBoot在2014年推出
Spring Boot是一个用于快速构建独立的、生产级的Spring应用程序的框架。它采用了约定大于配置的原则,通过自动配置和默认值设置,减少了繁琐的配置工作,提供了更简单、更轻量级的开发体验
Spring Boot还集成了一些常用的第三方库和工具,如内嵌的Servlet容器、自动化的构建工具(如Maven和Gradle)、健康检查、监控等,使开发者能够更快速地启动和运行Spring应用程序
-
总结
总体而言,Java企业级开发经历了从繁琐复杂的Java EE时代到简化灵活的Spring时代,再到更快速便捷的Spring Boot时代的演进
这些框架和工具的不断演进和创新,推动了Java开发领域的发展,为开发者提供了更好的工具和技术支持,助力他们构建出高质量、可扩展的企业级应用程序
现在在Java领域Spring已经形成了一种开发生态圈了,Spring提供了各个领域的开发解决方案,所以现在在任何Java项目中都有Spring的身影,有一句话叫做面向Spring编程,毫不夸张。Spring的这一套技术我们也称为Spring全家桶【spring,springJDBC,SpringMvc,SpringBoot,SpringCloud】
Spring简介
Spring框架全称SpringFramework,一般都简称为Spring
官网地址:https://spring.io/
在Spring中提供了很多的开源项目,这些开源项目为我们在Java开发中提供了各个领域的解决方案
在Spring全家桶中的众多项目中,SpringFramework项目是最为核心的,所有的项目都是基于Spring Framework的,其中SpringBoot是SpringFramework的高级版本
为什么不再选择Spring
-
在企业级开发中,我们选择Spring Framework进行开发,那么我们会面临两个问题
- 配置繁琐
- 入门难度大
SpringBoot中,很多配置都是已经默认配置好了,所以不再需要我们手动配置,但是Spring Framework则不然,这些配置不配置好就无法使用。同样的入门,在SpringFramework中可能需要半个小时,但是SpringBoot只需要5分钟
-
现在企业都在追求高效开发,因为高效就意味着高利润,所以市面上的Java项目基本上都是基于SpringBoot进行开发。官方目前也更加推荐使用SpringBoot作为Java开发,并且在后续的SpringCloud微服务项目中,我们也必须需要使用SpringBoot
-
使用SpringFramework开发web项目时,开发和部署都比较复杂,SpringBoot内置Tomcat,启动项目就像启动一个main方法一样的简单
SpringBoot入门
入门实现
搭建SpringBoot工程并实现浏览器与Java项目交互
实现步骤
第一步:使用SpringBoot骨架搭建SpringBoot项目
第二步:
- SpringBoot依赖有很多版本,我们学习使用SpringBoot-2.6.13
- 勾选初始化依赖,SpringBoot项目必须需要Web依赖,所以我们需要勾选Web依赖。其他依赖在以后项目使用中根据实际需要进行勾选
第三步:Springboot创建需要联网下载资源,等待构建完成即可
第四步:使用SpringBoot骨架进行创建会默认生成一些我们暂时使用不到的文件,为了项目简洁我们删除即可
第五步:创建请求处理类
- 请求处理类:专门用来接收前端发起到后端的请求
- 存储规范:请求处理类按照规范必须放入到controller包下
第六步:运行SpringBoot项目
- SpringBoot项目中定义了一个启动类,运行这个启动类可以把整个SpringBoot项目运行起来
第七步:浏览器访问
浏览器输入地址:http://localhost:8080/hello
项目结构:
访问原理解析
-
入门案例访问原理
1. 运行启动类启动项目,SpringBoot内置Tomcat,启动成功会看到控制台的默认端口号8080 2. 当在地址栏输入http://localhost:8080/hello时,浏览器访问的就是当前项目 3. 然后是用/hello去匹配我们的控制器Controller,即匹配注解@RequestMapping请求映射注解 4. 匹配上之后就会自动执行hello方法中的内容
注解:
@RestController // 创建当前类的对象
@RequestMapping("/hello/a") // 请求映射 - 匹配请求【从上下文路径后面开始算】,匹配上之后会执行当前方法的所有代码 - 实例方法【通过对象】
@RequestMapping("/hello/a")中的("/hello/a") // http://localhost:8080/上下文路径/hello/a
@SpringBootApplication // 申请当前类是一个SpringBootApplication的启动类 - 启动 - main方法启动
application.properties:
#端口
server.port=80
#应用的上下文路径,也可以称为项目路径,是构成url地址的一部分,就是在你所有的请求路径之前加了一个前缀
server.servlet.context-path=/
-
资源路径
-
URL
什么是URL:URL称为统一资源定位符,可以直接使用此地址找到互联网上的资源。例如:接口、页面
URL组成:协议名://IP地址:端口号/资源名称。例如:http://localhost:8080/hello
-
URI
什么是URI:URI统一资源标识符,俗称请求资源路径,URL地址中端口号后面的地址叫做URI。例如:/hello
-
“/hello/a”) // http://localhost:8080/上下文路径/hello/a
@SpringBootApplication // 申请当前类是一个SpringBootApplication的启动类 - 启动 - main方法启动
application.properties:
#端口
server.port=80
#应用的上下文路径,也可以称为项目路径,是构成url地址的一部分,就是在你所有的请求路径之前加了一个前缀
server.servlet.context-path=/
2. 资源路径
- URL
什么是URL:URL称为统一资源定位符,可以直接使用此地址找到互联网上的资源。例如:接口、页面
URL组成:协议名://IP地址:端口号/资源名称。例如:http://localhost:8080/hello
- URI
什么是URI:URI统一资源标识符,俗称请求资源路径,URL地址中端口号后面的地址叫做URI。例如:/hello
**区别**:URL包含URI,URI只是URL的一部分