Java学习路线
- Java基础:首先,你需要打好Java基础,包括语法、面向对象编程等。这是构建后续学习的基础,也是面试中的常见问题。(因为有之前的部分基础,所以只复习Java特有部分,其他快速过,数据结构与算法暂时跳过)
- Spring Boot / Spring MVC:Spring框架在Java开发中应用广泛,掌握Spring Boot和Spring MVC能够加速你对Java Web开发的理解和实践能力。
- MySQL:数据库是后端开发中不可或缺的一部分。学习MySQL的安装、基本操作命令以及与Java和Spring Boot的集成将有助于你理解数据存储和操作的原理。
- MySQL + Java + Spring Boot集成:学习MySQL数据库的安装、常用操作命令及基本原理,并将其与Java和Spring Boot集成,实践数据库操作和应用开发。
- Redis:Redis作为一种内存数据库,用于缓存和数据存储,学习其安装、常用操作命令以及与Java和Spring Boot的集成将为你的应用提供高效的数据管理方案。
- Redis + Java + Spring Boot集成:了解Redis的安装、常用操作命令及基本原理,并将其与Java和Spring Boot集成,实践缓存技术的应用和优化。
- Linux常用命令和虚拟机概念:作为后端开发人员,你需要在Linux环境下工作,因此熟悉常用的Linux命令和虚拟机概念是必要的。
- Elasticsearch:ES是一个流行的分布式搜索和分析引擎,掌握其与Spring Boot的集成将为你的项目提供强大的搜索功能。
- 消息队列(MQ):选择学习Kafka或Rocket MQ中的一个,消息队列在分布式系统中扮演着重要角色,学习其中一个将有助于你理解分布式系统中的消息传递机制。
- HTML/H5:虽然你的重点是后端开发,但了解前端基础知识也是有益的,特别是与后端进行交互时能够更好地理解前端开发的需求。
- 阿里巴巴代码规范:最后,阅读阿里巴巴的代码规范是很有价值的,它可以帮助你养成良好的编码习惯,提高代码的可读性和可维护性。
- 深入理解一个项目,开发几个模块:最后,通过深入理解一个项目并开发几个模块来实践所学知识,这将有助于你将理论知识应用到实际项目中,并锻炼你的项目开发能力。
基础
常用的windows组合键
- win + D 回到桌面
- win + E 启动资源管理器
- win + R 打开运行窗口
- win + L 锁屏
- alt + tab 应用之间的切换
常用的dos命令
- 打开dos命令窗口
按住win + R 输入cmd - 粘贴与复制
选中鼠标右击完成粘贴,再一次右击完成复制 - dir 显示当前路径下所有文件夹
- mkdir 创建文件夹
- cls 清屏
- exit 退出dos命令窗口
- 切换盘符 d:或者c:
- del + 文件名 (全删除 del + * .txt)
- dos命令可以用上下键翻命令使用记录
- ren abc xyz 将当前目录下的abc文件名改成xyz
- cd + 路径(带盘符的为绝对路径)或者相对路径(即以当前位置开始往后找)。
- cd + .. 回到上级目录 一次回到根目录直接cd
- 可以使用tab自动快速补全路径 - 在资源管理器中在路径处直接输入cmd可在对应位置打开dos命令窗口
- 批处理文件(多数为.bat文件,也可以为.exe文件)在文件内写批量dos命令。
- 把文件直接拖进命令窗口会生成其绝对路径
通用的文本编辑器快捷键
- 按住end光标回到行尾(按住ctrl+end 回到文件的末尾,光标往后选中一行按shift+end)
- 按住home光标回到行首(按住ctrl+home回到文件的开头,光标往前选中一行按shift+home)
- ctrl + shift +左右箭头可以选中一个单词或者鼠标双击
java基础
day1
- 类体中不能直接写java代码。
- 方法体中是由一行一行java代码组成且有自上而下的执行顺序。
- 在一个java程序中,如果符号是语言的一部分必须是英文半角(英文输入法)。
- 一个java源文件中可以定义多个class,编译之后一个class就会对应生成一个class字节码文件。但如果是public的类,其类名必须和源文件名保持一致,且只能有一个。
- 变量必须先声明再赋值才能访问。
- 同一个作用域中(一个大括号内),变量不能重名。出了大括号就不认识。
- 局部变量(凡是在方法体中定义的变量,且只在方法体中有效)
- 成员变量(在类体中定义的变量)
静态变量
实例变量 - 方法(可以重复使用的代码片段,提高代码复用性)一个功能一个方法。
day2
- 当调用一个返回值类型不是void的方法时,方法结束时会返回值,这个值可以采用变量接收,注意变量的类型,一般与返回值类型一致,或者能够自动类型转换,或者强制类型转换。
- 调用时,调用者和被调用者,在同一个类中可以省略类名.方法
- 方法如果只定义,不调用是不会分配内存空间,调用的瞬间会在栈内存当中分配活动场所,此时发生压栈动作。
- 方法重载:
应用场景:仅仅因为形式参数是的不同而定义不同名而功能相同的方法时,可以是使用重载(在一个类中定义多个方法,可以名字一致)。
条件:
1. 在同一个类中
2. 方法名一致
3. 形式参数列表不同(类型,顺序,个数)
4. 两个方法功能相似时,可以将方法名一致
优势:
1. 代码美观
2. 方法容易记忆,调用方便。
3. 方法重载是在编译阶段完成了方法的绑定。 - 方法递归
- 方法自己调用自己
- 需要有递归出口,不然栈内存会溢出出错。
- 递归太深还没到出口也会溢出,递归谨慎用,内存消耗大。循环涉及不到压栈,先推荐使用循环。
- 在实际开发中,如果因为递归调用发生了栈内存溢出错误:
首先可以调整栈内存大小,扩大栈内存。
如果扩大之后,运行一段时间后出现溢出错误,可能是因为出口有问题需要进行修改代码。
day3
- package和import
- package机制
- 语句只能出现在java源代码的第一行
- package com;(package 包名)
- 不同的类放在不同的包下,便于管理,便于查找和维护。
- javac -d . packagetest01.java (带包编译语法)
- 有了package之后,完整的类名是带包名的,所以运行的时候一定要添加包名: Java com.packagetest01
- 所有的包名都是小写
- import
- 在同一个包下调用可以省略包名
- 不是同一个类,要把包导入进来
- Java的lang包系统自动导入。
- import只能出现在package和class定义之间
- 支持模糊导入,类名可以省略,import Java.util.*
- package机制
day4面向对象
- 面向过程和面向对象编程的区别是什么?
- 面向过程编程:
- 这种编程方式将问题分解为一系列的步骤或过程,每个过程都是一段能够执行特定任务的代码。
- 数据和功能被分开,数据被视为被操作的对象,而功能则被视为对数据进行操作的函数或过程。
- 主要关注流程和函数的调用。
例子:想象你在做一道菜的时候,你会按照一系列的步骤来完成,比如先准备食材,然后切菜,炒菜,最后上桌。在面向过程的编程中,你会将每个步骤都表示为一个函数,比如prepareIngredients(),cutVegetables(),cook()等等。
- 面向对象编程:
- 这种编程方式将数据和操作数据的方法组合在一起,形成对象。对象是程序的基本单元,它封装了数据和操作数据的方法。
- 关注的是对象之间的交互和关系,通过定义类来创建对象,类中包含属性和方法。
例子:以汽车为例,面向对象编程将汽车视为一个对象,这个对象拥有属性(如颜色、品牌、速度等)和方法(如加速、减速、启动等)。当需要创建一个新的汽车时,只需实例化一个汽车对象,而不需要重复定义属性和方法。
简而言之,面向过程编程更加注重解决问题的步骤和过程,而面向对象编程更加注重组织和管理数据,以及数据之间的交互关系。对于小型、简单的项目,面向过程编程可能更为合适;而对于大型、复杂的项目,特别是需要长期维护和团队协作的项目,面向对象编程通常更具优势。两种编程思维。
- 类与对象
把事物与事物之间的共同特征(状态与行为)提取出来形成一个模板类(类= 属性(状态) + 方法(动作)),可以用类实例化多个对象(给属性值赋值的类)。 - 类中的方法不需要static修饰称作实例方法(对象方法),调用必须使用引用来调用,加上static的方法直接使用类名.调用(可能在测试程序里面定义)。
- 调用方法时参数是如何传的?方法中的参数实际上是变量中保存的值复制一份传给了方法。
- this关键字
- this指的是当前对象本质上是一个引用,保存的是当前对象的内存地址
- this.可以省略(在当前类中访问类中的实例变量时)
- this.age = age(用来区分局部变量和实例变量时不能省略)
- 封装机制
- 保存内部数据安全(在外部中,定义类中的变量不能随意访问)
- 独立体可以复用
- 步骤
- 在定义类中属性私有化,禁止外部属性对改属性随意访问,用private修饰。private int age
- 为了外部仍然可以访问,在定义类时需要提供访问入口(改和读)setter(编写语句对值进行过滤,保证属性安全)和getter(不涉及安全问题)方法 idea有快捷键
day6
- 在同一个类中,实例方法中调用实例方法,用this.方法名调用(可省略)因为到时候其他类中调用方法时肯定会创建对象,this就代表当前对象。
用static修饰的方法不能用this.调用实例变量和实例方法,省略更加不行。 - 构造方法
- 区别于实例方法和普通方法
- 作用
- 对象的创建(通过调用构造方法可以完成对象的创建)
- 对象的初始化(所有属性赋值)
- 后期改动还是用对外的setter方法,而不能再一次调用构造方法从而导致再创建一个新对象。
- 构造方法名必须与类名一致,用new 构造方法名 调用
- 不需要提供返回值类型
- new student(); 本质上是调用student类的无参数构造方法来完成对象的创建,无显示的构造方法时,系统会默认提供无参构造方法。
- 构造方法格式:修饰符 方法构造名(类名) 形参列表 {构造方法体;}
- 可以在类中定义显示的构造方法,在测试时可以完成对象创建的同时给对象属性赋值(不用的话,需要使用对象对外访问提供的setter方法进行赋值比较麻烦)
- 定义显示了构造方法,系统不会提供无参构造方法,建议手写出来。那么创建对象时,可以赋值或则不赋值。
- 一个类中可以创建多个构造方法,且自动构成方法重载
- 构造代码块
- 格式类体中{}
- 每一次new时会执行一次代码块
- 构造代码块是在构造方法之前执行的
- 作用:如果所有的构造方法在最开始的时候,有一段相同的代码,不妨提取出来为构造代码块。
- this关键字
- this出现在实例方法中,代表当前对象。
- this不能出现在静态方法中。
- this(实参) 通过这种语法可以在构造方法中调用本类中其他的构造方法。两个有参数的构造方法,其中一个可以调用另外一个进行赋值即可。代码少一点。构造方法中只能出现一次和第一行。
day7
- static关键字
- 应用背景:当所有对象的某个属性的值是相同的,建议将该属性定义为静态变量来节省内存。
- 所有的静态方法和变量,都是通过类名.访问
- Java中只有三种变量,成员变量,静态变量,局部变量:中国人类中的国籍变量可以设置为静态变量,因为所有的中国人对象国籍都是一样的。如果没有用static修饰的话,创建了多少对象就分配了多少个国籍变量,如果用static修饰,和对象没有关系,在中国人类加载时初始化储存在堆中。
- 静态方法中不能用this关键字。
- 静态代码块:
- 在类加载时执行,只执行一次(在main方法之前执行)
- 语法 static {}
- 可以有多个,遵循自上而下
- 在静态代码块中,无法直接访问实例相关的数据。
- 静态变量和静态代码块都是在类加载时执行,靠上下顺序执行
- 使用背景:给程序员提供类加载时刻:比如在类加载时记录日志
- 设计模式(可以重复利用的解决方案,软件设计经验的总结)
- 饿汉式单例模式(类加载时对象已经造好了)
- 只创建一个对象
- 实现:
- 构造方法私有化(无法使用new新建对象)对外提供公开静态的实例方法:public static 类名 get(){return s},定义一个静态变量 private static 类名 s = new 类名();
- 懒汉式单例(用在这个对象时再创建对象)
- 实现:
- 构造方法私有化
- 对外提供一个静态方法 在方法体中用一个判断语句,判断s是否为null ,是就new一个,不是就直接返回s即可。
- 定义一个静态变量 private static 类名 s;
- 实现:
- 饿汉式单例模式(类加载时对象已经造好了)
day8(方法覆盖和多态机制联合起来才有意义)
- 继承
- 作用:代码复用以及基于继承的方法覆盖和多态机制
- 实现:在定义B类时,在类名后面加上extends A类,既可以使用继承A类的变量和方法
- A类称为父类,superclass。B类称为子类,subclass。
- Java只支持单继承,一个类只继承一个类。
- Java不支持多继承,但支持多重继承(多层继承)
- 子类继承父类,私有属性不继承,构造方法不继承,其他全部继承
- 不显示继承,默认继承Java.lang.object类
- 方法覆盖
- 与方法重载的区别:重载机制是给编译机制看的
- 使用重写(覆盖)条件:
- 从父类继承的方法中个别方法不满足开发需求,需要重写。
- 具有相同的方法名(严格),形参列表(严格),返回值(可以是子类原本是object 可用string)。
- 具有继承关系的两个类。
- 在子类中重写父类的方法:直接去父类中复制方法粘贴过来,直接改。
- 在重写方法时上方加上@override进而编译器可以检查是否构成重写。
- 方法覆盖针对的是实例方法和静态方法无关。
- 方法覆盖针对的是实例方法,跟实例变量没有关系,不存在覆盖一说。编译阶段绑定是谁运行阶段就是谁,对于实例变量。
- 多态
- 基础语法
- 基本数据类型之间的转换
- 小容量转换为大容量,自动类型转换。
- 大容量转换为小容量,不能自动转换,必须要添加强制转换符。
- 引用类型之间的转换(两者要有继承关系)
- 向上转型:子转父(看作等同自动类型转换)
- 向下转型:父转子(强制转换)
- 向上:animal a1 = new cat();a1.move();编译时a1绑定的是animal类的move()方法在有此方法的情况下称为静态绑定(编译通过)。运行时,就会绑定cat对象的move方法,称作动态绑定。程序的两种状态。父类型引用指向子类型对象就是多态机制核心的语法。 当调用的为子类特有的方法时,需要向下转型。
- a1.run(),如果animal类中没有,那么在编译阶段就会报错。即使cat类中有。需要向下转型 cat a1 = (cat) a1。
- 向下转型容易出现class cast exception错误,可以使用instanceof判断来避免。
- 基本数据类型之间的转换
- 多态在开发中的作用
- 降低耦合,提高扩展
- 尽量使用多态,面向抽象编程,不要面向具体编程。
- 基础语法
day9
- 抽象方法
- 当定义抽象父类时,不知道实例方法写什么,大括号可以不写,用abstract修饰。它可以提醒你重写父类方法。位置顺序没有顺序。
- 抽象类
- 当类中有抽象方法时,类也需要变为抽象类。
- 抽象类虽然有构造方法但是不能实例化,是给子类实例化用的
- abstract不能与private(不能被继承),final(不能被重写),static(没有覆盖一说)共存。
- super关键字(区别于this关键字)
- super代表当前对象中的父类型特征
- super不能使用在静态上下文中
- 当然继承后使用this也可以访问父类的变量(前提是能继承的变量),访问父类还是统一为好,super可以当作this的一部分。
- 两者的区别在于父类和子类有相同变量或方法时,用以区分。
- 使用super进行重写,在父类的代码基础之上增加额外一段代码,在合适位置使用super.方法名()。?
- super可以代表多层继承的父类,往上的所有父类。即this可以单独输出,但是super不能单数输出。
- 由于构造方法不继承,当父类定义了有参构造时,子类也定义相关的有参构造,会有一些代码上的重复,这是可以用super(变量),就可以复用父类有参构造中的代码,即通过子类的构造方法调用父类的构造方法。
- 父类为无参构造时,子类构造方法时第一行没有显示调用时,系统会自动使用super()调用父类构造方法(给继承过来的变量初始化赋值)。
- this()和super()不能共存,因为他们只能出现在第一行。
- final关键字
- 表示最终的,修饰的类无法被继承
- final修饰的方法无法覆盖(重写)
- 修饰的值不能重新赋值
- final一般与static联合一起使用称为常量:public static final 数据类型 常量名 = 常量值。全部大写,用下划线分割。
- 修饰的引用类型,final product pro = new … 不能再指向新对象了即不能再new了。但是指向对象的内部数据可以修改。
day10
- 接口(interface)
- 接口和类一样是引用数据类型
- 接口为一种规范或契约,定义了一组抽象方法和常量
- 定义:把class替换为interface就可以
- 使用接口类型也可以定义引用。
- 抽象类是半抽象(可以定义抽象方法也可以不定义)的,接口是完全抽象的,接口无法实例化,也没有构造方法
- 接口之间可以多继承(区别类的多层继承)
- 类与接口之间的关系叫做实现(可以等同看作继承)使用implements关键字实现接口。可以实现多个接口,用逗号隔开
- 一个非抽象的类实现接口必须将接口中所有的抽象方法全部实现(强制)跟抽象类语法一样,对抽象方法重写。
- 使用接口之后,为了降低程序的耦合度,一定要接口与多态联合起来,即父类型的引用指向子类型的对象
- jdk8之后,接口中允许出现默认方法(必须有方法体)和静态方法(只能通过该接口名调用,其他无法调用)
- 9之后,可能静态方法和默认方法太多,进而出现允许定义私有的静态方法(给静态方法服务),允许定义私有的实例方法(给默认方法服务)。定义的私有方法在对应的静态和默认方法中调用。
- 所有接口隐式继承object类,可以调用其所有方法
- 作用
- 对于已经有的程序,增加新的功能时,需要改动多处代码,耦合度高。
- 接口总是有两方出现,即接口的实现者和调用者。
- 先把接口定义出来,再确定调用者和实现者,两者都是面向接口写代码。
- 接口和抽象类如何选择
- 在代码角度都能达到相同效果,但是适用场景不一样
- 抽象类适用于公共代码的提取,当多个类有共同的属性和方法时
- 接口用于功能的扩展,需要这个方法的类就去实现这个接口,不需要的就不去实现,接口主要规定的是行为。
- 一个类继承另一个类时还可以实现多个接口,接口和类可以没有继承关系。
day11
- 类中的属性和方法访问控制权限
- 四种访问权限:private 缺省的 protected public
- private只能在本类中访问
- public在任何位置都可以访问
- 缺省同一个包下可以访问
- protected在子类中可以访问(受保护的通常是给子孙用的)
- 类的访问权限只有两种public 和 缺省
- 这四个不适合修饰局部变量(方法中的变量)
- 异常处理机制
- 知道问题出现在哪里。
- 异常在Java中以类和对象的形式存在。
- 可抛出的异常
- error类错误(此类错误只能停止jvm的执行)
- exception(所有的异常都是可以处理之后可以运行的,都是在运行阶段出现的异常)
- runtimeException(由程序员引起的,可处理也可不处理)
- 其他都是编译时异常,检查异常,受控异常(要求在编写阶段进行预先处理,否则编译器会报错)
- 自定义异常步骤
- 选择继承runtimeException或则Exception(不是由程序员造成的都可继承)
- 异常类提供两个构造方法,一个无参,一个带参数(在方法中把参数往父类上传,用super(参数))
- throw new 自定义异常 使用时,有两者预处理方案,一种是在相关方法后用throws a(),b()或则父类异常 声明异常以便抛出(谁调用谁处理,不处理会一直往上抛到main,出错时jvm控制台报错后停止运行),另外一种是捕捉异常(捕捉自己处理)
- 自定义异常适合使用throws,使调用者知道
- 捕捉异常
- try{}catch(异常类型1 变量名){}catch(异常类型2 变量名)可以写多个,但是类型必须要从小到大。当有异常时,只会走一个分支,try块代码不会执行,其他域正常执行
- 需要让调用者知道就throws上抛到main用try捕捉处理。
- 异常的常用方法
- getMessage获取当时创建异常对象时给异常构造方法传递的string message参数的值
- printStackTrace打印异常堆栈信息红色字体,也包含定义时设定的异常信息。从栈顶看异常信息,看最开始的信息。
- finally语句块代码一定会执行(通常是完成资源的释放)
- finally不能单独使用,至少配合try 使用
- try …finally
- try…catch…finally
- 释放资源在try中可能不会执行,但在finally中一定会执行
- 第一种方式如果不用finally,出现异常没有捕捉,域后面的代码也不会执行
- 第二种域外的代码可以执行感觉用不用finally都可以。
- final是一个关键字,类无法继承,方法无法覆盖,变量无法修改
- finalize是一个标识符,是object类中的一个方法名
- finally不能单独使用,至少配合try 使用
- 方法覆盖与异常
- 重写之后抛出的异常只能更少不能更多
day12不足之处
- 在日常开发中,价格类为什么用float修饰更合适?
精度需求: float类型能够满足价格类数据保留小数点后的精度需求,例如货币计算中涉及的小数位。
计算效率: float类型在计算上比较高效,因为通常由硬件直接支持,可以快速完成价格计算。
内存占用: float类型通常占用较少内存空间,适用于需要处理大量价格数据的系统,能够有效节省内存资源。
虽然float类型通常是合适的选择,但需要注意其精度有限,可能在特定情况下导致精度损失或舍入误差。对于需要更高精度的场景,可以考虑使用decimal类型或其他精度更高的数据类型。 - 枚举类的使用不熟悉
- 跨包使用使用类以及变量需要导入
- 数据结构的创建一起使用不熟悉
- 测试类的编写不太熟悉
- 多看看开发手册吧。。。
maven快速入门
学习Spring Boot和Spring MVC之前,建议先对Maven有一定的了解和掌握,因为Maven是Java项目管理和构建的重要工具,而Spring Boot和Spring MVC项目通常都是通过Maven来管理依赖和构建的。
- Maven对于Java可以类比于pip对于Python。
- Maven:Maven是Java项目管理和构建工具,用于管理Java项目的依赖、构建、测试、部署等任务。通过Maven,可以定义项目的结构、依赖关系和构建过程,并利用Maven提供的命令来执行这些任务。Maven使用XML格式的配置文件(pom.xml)来描述项目的元数据和构建配置。
- pip:pip是Python的包管理工具,用于安装、卸载、管理Python包。通过pip,可以轻松地安装Python包,并管理项目所需的依赖关系。pip通常与Python的虚拟环境结合使用,以便在项目之间隔离不同的依赖关系。
day12
- 管理或下载第三方依赖
- 构建项目(是一个过程)
- 可以使用Maven来构建、测试和打包这个Java应用程序
- 使用Maven构建Java应用程序时,最终会将项目打包为JAR(Java Archive)格式的文件。JAR文件是Java平台上常用的归档文件格式,用于将多个Java类文件、资源文件和依赖库打包成一个单独的可执行文件 (通常指的是有jdk即可)。
- 当你使用JAR文件部署项目时,无需额外安装项目所依赖的库,只需确保目标环境有对应的Java运行时环境即可。而直接使用.class文件则无法包含项目的依赖库,因此在部署项目时需要手动处理项目的依赖关系,包括添加依赖库的路径、管理依赖的版本等。这增加了部署和配置的复杂度,降低了项目的可移植性。因此,对于大多数项目来说,使用JAR文件打包项目是更好的选择,因为它具有更好的依赖管理和可移植性。
- 可以分享依赖(上传到服务器)
- 通过将Maven(打包)、Jenkins(跟GitHub action 功能相似)和Docker结合使用,可以实现从代码提交到Docker容器部署的完整自动化流程。这种自动化流程可以极大地提高软件开发和部署的效率,同时保证了项目的一致性和可重复性。
- jar包相当于python的第三方库
- 产生背景
- 管理庞大的jar包,需要专门的工具
- 脱离IDE环境仍需要构建,需要专门的工具如服务器环境部署(IntelliJ IDEA 默认情况下会自动构建项目,但它使用的是 Maven 或者 Gradle 这样的构建工具进行项目构建,构建的输出通常会放置在 Maven 或 Gradle 指定的输出目录中,对于 Maven 项目通常是 target 目录,而对于 Gradle 项目则是 build 目录)
- 普通Java项目的out文件夹:在普通的 Java 项目中,out 文件夹通常是 IntelliJ IDEA 自动生成的输出目录,用于存放编译后的 .class 文件和其他构建产物。这个目录是 IDEA 的默认输出目录,如果你没有自定义,它会将编译后的类文件输出到该目录中。通常情况下,你可以在 out 目录中找到编译后的 .class 文件,这些文件是你的 Java 代码经过编译后生成的字节码文件。IDEA 会将这些文件生成到 out 目录中,以便在你运行或调试程序时使用。虽然 out 目录是自动生成的,默认情况下你不应该手动编辑其中的文件,因为它们会在下次项目构建时被覆盖。如果你需要手动添加或修改输出文件,应该将它们放置在源代码目录之外,或者在 IntelliJ IDEA 中配置自定义的输出目录。
- Maven 的工作原理是基于项目对象模型(POM)、依赖管理、生命周期和插件的概念(jar包),通过配置 POM 文件和执行 Maven 命令来实现项目的构建、依赖管理和项目信息管理。
- 当你创建一个 Maven 项目时,IntelliJ IDEA 会自动检测并提示你是否需要下载和安装 Maven。如果你选择下载并安装,IDEA 会自动配置项目使用已安装的 Maven,并为你创建一个默认的 Maven 配置文件(pom.xml)。因此,如果你只是在 IntelliJ IDEA 中开发 Maven 项目,并且不需要在命令行中执行 Maven 命令,使用 IDEA 提供的内置 Maven 功能可能会是一个更好的选择。
- idea自带的无法指向正确setting.xml,改为使用安装maven的配置
- 基于idea创建maven项目
- 相较于之前的项目创建多出了一组GAVP属性
- GAVP 属性代表了项目的坐标信息,包括 GroupId、ArtifactId、Version、Packaging
- GroupId:这通常是公司或组织的唯一标识符。例如:com.example
- ArtifactId:这是项目的唯一标识符(产品线名-模块名)。例如:my-project
- Version:项目的版本号。通常是 1.0-SNAPSHOT。
- Packaging:项目打包方式,通常是 jar(默认) 或 war或pom。
- 每新建一个项目maven配置都会重置,需要重新配置
- .idea 目录提供了项目配置的功能,包括了 .iml 文件所包含的信息。.iml 文件是其中的一部分,保存了单个模块的配置。
day13
- 基于idea创建maven的web工程
- 与普通的maven的Java工程的区别就是少了web模块,直接在pom文件中把打包方式改成war即可在右边刷新。
- 在项目结构中点击出现的web,点击加号把路径补充为下方指定的路径点击应用就会出现webapp下web.xml
- 可以使用插件JavaToWeb创建maven的Java工程后右键点击转换。
- 可以使用自带的maven archetype,只不过web.xml版本比较低。
- 部署到tomcat的教程有需要再看。
- maven工程项目结构说明
project-name
│
├── src
│ ├── main
│ │ ├── java # 主要的 Java 源代码
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── controller # 控制器类
│ │ │ ├── model # 数据模型类
│ │ │ └── service # 服务类
│ │ │
│ │ ├── resources # 主要的资源文件
│ │ │ ├── config # 配置文件
│ │ │ ├── static # 静态资源(CSS、JavaScript等)
│ │ │ └── templates # 模板文件(Thymeleaf、Freemarker等)
│ │ │
│ │ └── webapp # Web 应用程序相关的资源
│ │ ├── WEB-INF
│ │ │ └── views # 视图文件(JSP、HTML等)
│ │ └── resources # 其他资源(图片、字体等)
│ │
│ └── test
│ ├── java # 测试用的 Java 源代码
│ └── resources # 测试用的资源文件
│
├── target # 编译和构建产生的输出目录
│
├── pom.xml # Maven 项目描述文件
└── ...
src/main/java:主要的 Java 源代码目录。所有的主要源代码应该放在这里。当你运行 Maven 的编译命令时,编译后的类文件会存放在target/classes目录中。src/main/resources:主要的资源文件目录。这包括配置文件、属性文件、日志配置等。这些资源文件在构建时会被复制到target/classes目录中。src/main/webapp:如果你正在开发一个 Web 应用程序,那么你的 Web 相关资源应该放在这里。这可能包括 HTML 页面、CSS 文件、JavaScript 文件等。在构建时,这些资源会被复制到 WAR 文件的根目录下。src/test/java:测试用的 Java 源代码目录。所有的单元测试和集成测试代码应该放在这里。测试类通常与主要的 Java 类相对应,并且类名以Test结尾。src/test/resources:测试用的资源文件目录。这些资源文件可以被测试代码引用,通常用于提供测试数据或者配置文件。target:Maven 的输出目录。这是 Maven 构建时生成的所有文件的默认存放位置,包括编译后的类文件、打包后的 JAR/WAR 文件等。pom.xml:Maven 项目描述文件。它定义了项目的元数据、依赖关系、构建配置等信息。该文件遵循 XML 格式,并包含了项目的基本结构和配置。- 构建命令之编译和清理
- 清理(Clean):
mvn clean清理命令会删除 target 目录及其子目录中生成的所有构建输出,包括编译后的类文件、打包的 JAR/WAR 文件以及生成的测试报告等。 - 编译(Compile):
mvn compile编译命令会编译项目的源代码,并将编译后的类文件存放在 target/classes 目录中。 - 测试(Test):
mvn test测试命令会执行项目的单元测试,并生成测试报告。测试报告通常存放在 target/surefire-reports 目录中。 - 报告(Report):
mvn site报告命令会生成项目的各种报告,如代码覆盖率报告、静态代码分析报告等,并将这些报告存放在 target/site 目录中。 - 打包(Package):
mvn package打包命令会将项目的编译后的类文件和相关资源文件打包成 JAR/WAR 文件,并存放在 target 目录中。 - 安装(Install):
mvn install安装命令会将项目的构建产物(通常是 JAR/WAR 文件)安装到本地 Maven 仓库中,以便其他项目可以引用和依赖它。部署(Deploy):mvn deploy部署命令会将项目的构建产物(通常是 JAR/WAR 文件)部署到远程仓库或者服务器上,以便其他项目可以访问和使用它。 - 构建相关的命令必须要在项目的pom.xml的目录中使用
- 测试类(test结尾)和测试方法(建议test打头)命令有要求
- 命名规范之后用test命令后报告自动生成
- 打包(进行了多个操作)之后的jar命令也是有规范的,项目名+maven工程版本组成
- jar包里面不包含测试程序只包含核心程序,能打包说明经过测试的,没必要包含
- war包打包插件与jdk版本不匹配可以在pom中引入相关依赖
- 所有的包都是通过坐标进行安装的在本地maven仓库中
- 在idea中右边的工具栏可以可视化直接执行。
- 生命周期下的plugins就是支持构建命令的相关插件
- 构建插件、命令、生命周期命令之间的关系
- 构建插件定义了具体的构建任务(怎么做),命令表示了插件中的具体操作(做什么),生命周期定义了构建过程中的各个阶段,而生命周期命令则与生命周期阶段相关联,指定了在特定阶段执行的具体任务。这些概念共同构成了 Maven 构建过程的基础架构。
- 执行打包时,会执行前面的过程。简化了构建过程
- 清理(Clean):
- 依赖管理
- Maven 会读取 pom.xml 文件,并检查其中声明的依赖项,然后根据这些信息来下载和管理项目的依赖。
- 一旦 Maven 解析了项目的依赖关系,它会检查本地 Maven 仓库以查看是否已经存在所需的依赖。如果本地仓库中不存在相应的依赖,Maven 将从远程仓库(通常是 Maven 中央仓库)下载所需的依赖文件,并将其保存到本地仓库中。
- 即使你勾选了删除依赖文件的选项,IDEA 也只会删除该项目直接引用的依赖,而不会删除其他项目可能依赖的相同依赖。因此,在删除项目时,最好还是手动检查并决定是否删除相关的依赖文件,以确保不会影响其他项目的构建和运行。
- 只需要关心核心jar包,其他核心jar包依赖的包都交给maven管理与下载
- 依赖的维护(能修改的也只能是版本)
- 在properties中对依赖版本进行自定义属性限定,达到统一管理一些类jar包版本的目的
- 在dependency中使用应用属性即可
- 依赖的范围
- compile:编译范围。该依赖在编译、测试、运行以及打包阶段都是可用的。这是默认的依赖范围,如果没有明确指定,Maven 会使用该范围。
- provided:提供范围。该依赖在编译和测试阶段是可用的,但在运行时是由目标环境(例如 Servlet 容器)提供的,因此在打包阶段不会包含在最终的部署包中。
- runtime:运行时范围。该依赖在测试和运行时是可用的,但在编译阶段不需要,因此在编译阶段不会包含在最终的编译结果中。
- test:测试范围。该依赖仅在测试阶段可用,并且不会被包含在最终的编译结果或部署包中。通常用于编写测试代码时所需的依赖。
- system:系统范围。该依赖类似于 provided 范围,但需要显式指定路径,通常用于引入本地系统中的 JAR 文件。在编译、测试和运行时都可用,但在打包阶段不会包含在最终的部署包中。
- import:导入范围。该依赖仅在
<dependencyManagement>部分中使用,用于从其他 Maven 项目中导入依赖的管理信息,而不实际导入依赖本身。
- maven依赖下载失败
- 网络问题
- 修改了版本号而远程仓库没有这个版本(只要查到了有版本,才可以改坐标)
- 下载一半失败,通过坐标去仓库位置把清除缓存文件(lastupdate)删除
- maven依赖的传递性
- 假设项目 A 依赖于项目 B,并且项目 B 依赖于项目 C。当你在项目 A 的 pom.xml 文件中声明了对项目 B 的依赖时,Maven 会自动检测到项目 B 的依赖,然后继续检测项目 B 对项目 C 的依赖,并将项目 C 的依赖也添加到项目 A 的依赖中。依赖传递性使得 Maven 能够自动管理项目的依赖关系,避免手动处理每个依赖及其传递性依赖的问题。这简化了项目的配置和维护,并确保项目的构建和运行所需的所有依赖都能够被正确地解析和使用。
- 当一个工程间接或者直接引用了相同的jar包即一个项目出现相同的重复jar包,可能会发生冲突。maven有自动解决依赖冲突的能力
- maven工程的继承和聚合关系
- Maven 的继承是一种机制,允许你在多个 Maven 项目之间共享配置信息和依赖管理。通过继承,你可以定义一个父项目(也称为聚合项目或者超级项目),然后让其他项目继承这个父项目的配置信息和依赖管理。
- 通过 Maven 的继承机制,可以实现以下几个目的:
- 代码重用:可以将多个 Maven 项目中的公共配置信息和依赖管理提取到一个父项目中,避免重复配置。
- 标准化配置:可以通过父项目来定义标准化的配置规范,确保所有的子项目都遵循相同的配置规则。
- 依赖管理:可以统一管理多个项目的依赖,确保所有项目使用相同版本的依赖库,避免依赖冲突。
- 要创建一个具有继承关系的 Maven 项目,通常的做法是创建一个父项目和多个子项目,并在子项目的 pom.xml 文件中指定父项目的坐标信息。这样就可以实现父项目和子项目之间的继承关系,并享受到共享配置和依赖管理的好处
- maven工程的聚合
- 通过 Maven 工程聚合,可以实现以下几个目的:
- 统一管理:通过父项目统一管理多个相关联的子项目,包括共享的配置信息和依赖管理。
- 构建顺序:Maven 会自动按照父子项目的依赖关系来确定构建顺序,确保子项目在构建时能够正确地解决依赖关系。
- 组织结构:通过聚合,可以将相关的 Maven 项目组织在一起,形成一个逻辑上的整体。这样可以更清晰地理解项目的结构和关系。
- 要创建一个 Maven 工程聚合,通常的做法是创建一个父项目和多个子项目,并在子项目的 pom.xml 文件中指定父项目的坐标信息。然后,可以使用 Maven 的命令来管理和构建整个聚合项目,包括对父项目和子项目的操作。
- 在 IDEA 中,如果依赖已经正确地显示在项目依赖中,而你无法在本地 Maven 仓库中找到它们,通常情况下是因为 IDEA 使用了自己的缓存来管理依赖,而不是依赖直接放在本地 Maven 仓库中。 IDEA 会在其自己的缓存中管理依赖,并且不像 Maven 那样把它们直接下载到本地 Maven 仓库。 因此,只要在 IDEA 中正确显示了依赖,并且项目能够正常编译和运行,你就不需要过于担心依赖是否存在于本地 Maven 仓库中。
- 如果你在 IntelliJ IDEA 中直接删除了 Maven 项目,IDEA 会删除项目文件和配置,但它不会自动删除你在本地 Maven 仓库中下载的依赖。这意味着你需要手动删除本地 Maven 仓库中与你删除的项目相关的依赖。