前两天我说要写个项目来持续迭代,有好多小伙伴都表示支持和鼓励,项目的第一篇这不就来了么~我给项目取了个名字,英文名叫做:austin,中文名叫做:奥斯丁

名字倒没有什么特别的含义,我单纯觉得这个名字好看,说白了就是我喜欢。在起项目名的时候,可以不要取得那么规矩。取系统名字可以按自己想法来搞就行了,人家只要用了你的系统,就自然「入乡随俗」了。不聊别的了,进入今天的主题吧。

从零开始一个项目,也得搭建技术环境的,所以今天先来聊聊搭建技术环境的内容吧

本文主题大纲:Maven和SpringBoot以及Git

什么是Maven?为什么要用Maven?

Maven是一个「项目管理」的工具

我记得以前我在大学的时候,还没用到Maven,每次学习最头疼的就是各种的依赖jar包。当我学习到Maven的时候,这个工具给我的第一感觉就是:这东西就是一个「依赖包管理」的工具

初体验之后,直呼太TM香了!再也不用到处去找jar包了!

其实,Maven不仅仅承担着「依赖包管理」功能,同时他在日常开发使用中也承担着「编译」、「测试」、「打包」、「部署」等等功能。

我在日常开发中常用到的maven命令:

1、mvn compile
2、mvn test
3、mvn clean
4、mvn pakage
5、mvn install
6、mvn deploy
7、mvn versions:set -DnewVersion=xxxx  设置Maven的版本
8、mvn dependency:tree  查看maven的依赖树(排查依赖很有效)

常用参数
-Dmaven.test.skip=true
-Dmaven.javadoc.skip=true

现在Java后端项目很多都是用Maven来作为「项目管理」的工具,至少我接触的都是。

有的人就好奇了:近几年不是有个后起之秀Gradle

说实话,我是没用过(:不过我也去简单了解了一番。

据我了解到的,总的来说,Gradle比Maven更灵活和简洁,目前多用在Android项目上。还有很重要的一点,相对Maven而言,Gradle学习成本更大

现在Java后端的项目也越来越轻量,很多时候也不需要那么地”灵活“(Maven提供的功能基本够用)。对于简洁来说,XML也不是不能看(毕竟现在大家都在IDE上开发嘛)。所以,这次我构建的项目也直接用的Maven

不过啊,因为我是没深度使用过Gradle,所以也不能说我用Maven比Gradle一定要合适(:但至少,在现在,我认为Maven还能战10年

为什么SpringBoot

这次我选用SpringBoot作为项目的基础环境,至于为什么SpringBoot,我先跟大家分享下群里的对话。

我记得有一天,有个小伙伴在群里问:今天我去面试了,面试官问我使用SpringBoot有什么好处

接着,另一个小伙伴回答:使用SpringBoot最大的好处,就是让我这种垃圾水平的开发都入了行,做上了程序员。

我在大学时是学过SSH和SSM的,我学这些的时候还没用Maven,那时候搭建环境就尤其麻烦了。(当时还专门写了博客记录自己是如何整合SSH和SSM的)

一个项目里会用好几种技术栈,不同的技术栈就需要有对应的配置(常见的Spring、SpringMVC、Mybatis)等等,然后这些技术都需要兼容对应的版本(一般我们是把这些技术整合到Spring上的)。当我们要引入新的框架,那自然就需要对齐Spring版本并且有对应的配置文件。

那时候真的是配置地狱(框架们都做得灵活,都支持我们把可能需要改动的内容写到XML配置上,但随着时间流逝,我们渐渐发现:这些XML配置我们都维护不动了...)

基于这种背景下,SpringBoot应运而生,它最明显的就是简化了我们开发的配置工作。当一项技术能减少开发时工作量都有一个特点:约定大于配置(开箱即用)

只要引入了SpringBoot,那只要通过几行的代码就能快速地从零写出对应的HTTP接口(可参考官网SpringBoot 的Quick Start)

从零构建Java项目(Maven+SpringBoot+Git) #02 奥斯丁项目-LMLPHP

以前我们干这种事,需要整合SpringMVC,需要配置一个Tomcat服务器,需要对齐它们的版本(是否兼容)....

我认为SpringBoot作为使用方,要了解以下两块内容:

一、当我们项目我们引入了SpringBoot的依赖(spring-boot-starter-parent),点进去parent就会发现spring-boot-dependencies这个pom定义了非常多「默认的依赖」。这使得我们在项目中使用的时候,都不用写版本了(因为SpringBoot已经默认帮我们已经写上了),还不用担心版本冲突的问题(:

二、在启动SpringBoot项目的时候,还会帮我们初始化很多默认的配置。(这里也是一个面试经常考察的地方「自动配置」)。总的来说,@SpringBootApplication等同于下面三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!

现在新写的Java后端项目,基本都是用SpringBoot作为开发环境了(:毕竟是真的爽

作为程序员,我最烦的就是搞各种环境配置和版本依赖的问题(真正的脏累活),虽然很多时候只用搞一次,但是感觉很多时候就真的如下图:

从零构建Java项目(Maven+SpringBoot+Git) #02 奥斯丁项目-LMLPHP

为什么项目结构是多模块?

我搭建了项目,取了个名字叫:austin,然后我在IDE上新建了几个Maven Module,目前分别是(后面可能还会新增):

  • common(基本信息->POJO/枚举配置)
  • support(Data获取->DB/Redis/Elasticsearch)
  • service-api(服务接口)
  • service-api-imp(服务接口实现)
  • web(HTTP接口)

从零构建Java项目(Maven+SpringBoot+Git) #02 奥斯丁项目-LMLPHP

最开始我们初学写代码的时候,可没那么讲究,直接在一个包下一把梭就完事了(:

后来,他们说要分包,不同模块的代码写到不同的包上。于是我们会在项目下新建对应包(其实就是文件夹),比如说dao/service/controller

而到现在,基本都是分模块了,不同职责的代码被分到对应的模块上。而austin直属下的pom文件就一般只用来管理依赖(把依赖和版本信息定义在父pom上,具体哪个子模块需要引入就好了)

<dependencyManagement>
  <dependencies>
    <!--mysql驱动包-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.35</version>
    </dependency>
  </dependencies>
</dependencyManagement>

那么这种分模块又比以前分包好在哪里呢?

假设我们是分包的,那相当于所有的代码写到一个模块上。每次当我们修改时,我们需要重新编译整个模块(可能我只改了Dao包的某个实现类,但在编译的时候会把整个模块都编译一遍)。

如果是分模块的话,我们直接到模块下 mvn compile -Dmaven.test.skip=true 就完事了。

不过这只是一个方面,说服力好像也不太足。我认为最主要的是,我们分模块了以后可以复用

比如,现在我有austin这个项目,此时为了对数据进行处理,我需要去新建对应的Flink应用。可能受限于环境下,不会把flink相关的代码写在austin项目下

(这也只是举了个例子,我想表达的是:一个成熟的项目往往不只有一个Git地址就覆盖了整个功能。在绝大多数时候,不同的功能都会分开到不同的项目上)。

那不同的项目下,很有可能需要做的事情是有重复的(比如我都需要去读数据库获取数据)。那这时候,分模块的好处就体现出来了:可以直接引入对应的jar包(比如support包和common包)。

那就不用在两个不同的项目上,写一模一样的代码了(:能够共用一套代码

有没有小伙伴好奇为什么apiapi-impl是分了两个模块的吗?这里是为了:如果以后引入了RPC调用,那我们只需要提供api模块出去就好了,api模块的依赖一般很少。

(解决版本冲突是一件脏累活,人家嵌入你的SDK只是想用你的服务去获取对应信息,你别给人家整了一大堆毫无作用的依赖出来)

为什么Git

到这里,项目的架子已经搭好了。我要把项目上传到Gitee跟大家愉快地玩耍(:

Git是一个版本控制工具。把austin被Git管理后,我每次提交的内容都会被看到(:这在多人协作中尤其重要

除此之外,有了“版本”的概念以后,用Git可以随意回退版本(有后悔药吃

我当时刚出来实习的时候,那家公司用的是SVN(我当时对版本控制工具理解其实是很模糊的,反正在我当时看来,就是把写好的代码上传到中央服务器,只不过它能对比出每次修改的异同)

后来以后,在公司接触都是Git了(现在开发基本离不开Git了,这玩意本身还是比较好学的,用起来还是挺爽的)

顺便发一波我日常用到的Git命令吧:

1. git clone  (克隆代码)
2. git checkout -b (新建分支)
3. git checkout (切换分支)
4. git add / git commit /git push (这几步我基本都是在IDE上用快捷键完成,很少自己敲命令)
5. git fetch (获取最新的修改信息)
6. git merge (合并代码)
7. git stash /git pop (有的时候临时会用,把代码放到暂存区中)
8. git reset --hard  (代码写烂了,直接回退吧)

一般Git我是一半用命令行,一半用IDE集成的工具。总的来说,怎么舒服怎么来(没有限定说一定要用命令行,我是自己怎么操作比较快就怎么搞)

对于这个项目而言,我这里使用到Git最大的原因就是:有远程的仓库装载我的代码,并且你们能看到(:

Gitee链接:https://gitee.com/austin

GitHub链接:https://github.com/austin

总结

说实话,如果还没工作的人,我建议多学学Maven和Git的基本使用(这样一来,去到公司就不用一脸懵逼了)

对于SpringBoot的学习是永无止境的,我个人的理解是,在了解了用法以后,可以尝试面向「面试题」进行学习(毕竟面试题面的内容大多数都是比较核心的,至少不是偏门没有任何用途的)

austin项目构建:

  • Maven:依赖包管径+项目管理(多模块)
  • SpringBoot:基础技术环境搭建(开箱即用)
  • Git:版本控制工具(代码上传至远程Gitee)

今天就到这里吧。我花了一个晚上搭建了架子,两个晚上写了这篇文章。自从有了这个迭代项目的想法以后,晚上的效率嘎嘎地就上去了。

欢迎关注我的微信公众号【Java3y】来聊聊Java面试,对线面试官系列持续更新中!

从零构建Java项目(Maven+SpringBoot+Git) #02 奥斯丁项目-LMLPHP

【对线面试官+从零编写Java项目】 持续高强度更新中!求star

12-07 12:50