为了账号安全,请及时绑定邮箱和手机立即绑定
2. 传递性依赖

目前我们的项目只引用了两个依赖,spring-boot-starter 和 spring-boot-starter-test,但是是这样子的吗?为了能够更清晰的看到我们项目依赖的结构,我们可以在 IDEA 里面安装 Maven Helper 插件。安装好之后,我们打开项目的 pom.xml 文件,可以看到在文件的下方多了一个 Dependency Analyzer按钮。打开之后,如下图。从这里我们就可以看到,其实我们不只是引入了两个包,而是引入了很多个包,这是为什么呢?答案是因为 Maven 的传递性依赖机制。在我们这个项目中,我们引入了 spring-boot-starter 依赖,并且该依赖的范围是 compile,但是 spring-boot-starter 作为一个项目也有自己的依赖,在这其中的依赖范围为 compile 的依赖,则会自动转换成我们项目的依赖,例如 spring-boot 依赖,logback-core 依赖。所以,有了 Maven 的传递性依赖机制之后,我们在使用一个依赖的时候,就不再需要考虑它又依赖了哪些,而是直接使用即可,其他的事情 Maven 会自动帮我们做完。

3.2 添加依赖包

项目创建成功后,会发现项目上有红色的错误提示,这个不用紧张。因为项目自动创建了一个 jsp 文件,而 jsp 所依赖的 servlet 包我们还没有加进来。打开项目中的 pom.xml 文件,在文件中添加项目所需要的依赖 jar 包:javax.servlet-api: servlet 规范包;spring-context: spring 最基础、最重要的核心包。Maven 有一个依赖传递功能,会自动添加 spring-context 所依赖的其它包;spring-web: spring 对 web 项目的支持包,这个不用解释,肯定不能少;spring-webmvc: 从名字上看,知道它应该是主角,Spring MVC 核心包。完整的依赖信息如下:<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.13.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.13.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.13.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency></dependencies>Maven 会自动从远程仓库下载这些依赖包,项目中也可以看到下载下来的依赖包:大家会看到,除了在 pom.xml 文件中指定的依赖包外,还有其它的包,这个就是 Maven 的依赖传递功能实现的。好了! 有了这些包后,就可以使用 Spring 提供的 WEB MVC API 了。

1. 何为依赖?

依赖即为本项目对其他项目的引用,这里的其他项目可以是外部项目,也可以是内部项目。我们在开发项目的过程中,将其他项目作为依赖引用进来,最终在打包的过程中,依赖会和我们开发的项目打包到一起来运行。在我们的项目没有使用 Maven 的时候,我们需要手动去管理我们的依赖,例如:添加依赖,删除依赖。在使用了 Maven 之后,我们可以在 pom.xml 文件里面看到我们所有的依赖,并且可以灵活的管理项目的依赖。在上图中,我们可以清晰的看到我们项目目前所引用的依赖。

3. 添加依赖

项目新建后,在项目根目录下找到 pom.xml文件,并向其中添加如下配置。<dependencies> <!-- MyBatis 依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <!-- mysql 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> <!-- 日志依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency></dependencies><!-- 文件打包配置 --><build> <resources> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> </includes> <filtering>false</filtering> </resource> </resources></build>添加的依赖比较多,虽然在相应的地方我们也打上了注释,不过我们依然得说明一下。dependency 是 Maven 管理依赖的方式,我们分别添加了 mybatis、mysql-connector-java 和 logback-classic。其中 MyBatis 作为我们的主角,它的依赖是必不可少的;由于实操需要数据库环境,我们也添加上了 MySQL 驱动依赖;为了更好的查看信息,我们也添加了 logback 日志框架。另外,由于 Maven 打包默认不会打包 src/main/java文件夹下的资源文件,但实际的环境中,我们可能需要在该文件夹下存放资源文件,如.xml,所以我们也必须更改这个配置。添加依赖后,IDE 会提供你是否导入这些依赖,请你点击确认,并且等待一会儿,待依赖导入完成我们就可以进入下一步了。

1.2 添加一个依赖

使用 yarn add 命令,如添加vue-cli依赖:yarn add vue-cli如果不写版本号,默认安装最新版本,如果需要安装指定版本,请按照如下格式添加依赖:yarn add vue-cli@x.x.x此操作将自动在 package.json中添加对应的依赖,同时更新yarn.lock文件的版本信息。我们还可以添加依赖到其他类型的依赖关系如:yarn add --dev 添加到 devDependenciesyarn add --peer 添加到 peerDependenciesyarn add --optional 添加到 optionalDependencies具体的依赖关系类型,yarn的官网列举如下:最后,我们执行 yarn add vue-cli,出现 success信息,并提示我们具体安包的数量,说明依赖安装成功 效果如图:我们可以看到我们的package.json文件中多出了预想的依赖信息,并且项目目录中多出了 node_modules 文件夹,所有的依赖相关文件都被安装在了这个文件夹中,大功告成!

2. 预装依赖包

Nginx 是完全用 c 语言编写的,所以想要编译 Nginx,必须要有 c 编译器(gcc), 只要系统里有 gcc, Nginx 就可以编译安装。但是往往我们会用的到 Nginx 的一些重要功能,比如压缩和解压缩功能,这时就必须需要依赖 zlib 库,想在配置文件中使用正则表达式,就必须安装 pcre 库,最后想实现 SSL/TLS 功能,必须安装 openssl 库。无论是在 Ubuntu 还是 CentOS 系统中都大致如此,只不过管理软件包的工具不一样,依赖库的名称也不一样。在 Ubuntu 系统下,在 Ubuntu 中执行如下命令安装依赖库:$ sudo apt-get update # 更新下apt源$ sudo apt-get install gcc # Nginx必备$ sudo apt-get install make # 编译安装需要make工具$ sudo apt-get install libz-dev$ sudo apt-get install libpcre3-dev$ sudo apt-get install libssl-dev

2.2 依赖管理

其实问题并没有完全解决,并不是所有的子模块都需要引入 fastjson-1.2.49.jar 这个依赖,那要怎么办呢?在 POM 中,我们可以在父模块中声明 dependencyManagement 元素,让子模块来继承。dependencyManagement 元素并不会实际的引入依赖,但是可以起到很好的约束依赖的作用。首先,我们在父模块的 pom.xml 文件中声明这个元素,并加入 fastjson-1.2.49.jar 这个依赖。<properties> <fastjson.version>1.2.49</fastjson.version></properties><dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> </dependencies></dependencyManagement>然后,我们在 mall-core 模块中添加这个依赖,但是我们并不需要再声明version。<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency></dependencies>这时候,我们分别查看父模块与子模块所引入的依赖,会发现,只有子模块中有引入这个依赖,而父模块中,并没有。父模块依赖引入情况 而子模块中已经引入了这个依赖。 子模块依赖引入情况 我们通过 Maven 继承的特性,来进行依赖管理,可以更好的控制依赖的引入。而 Maven 对于插件的管理,也存在类似的元素可以使用(pluginmanagement 元素),可以做到相同的效果。

1.1 依赖的范围

Maven 在编译和运行以及执行测试用例的时候,分别会使用不同的 classpath。而 Maven 的依赖范围则是用来控制依赖与不同 classpath 关系的。Maven 的依赖范围分为以下几种:compile: 编译依赖范围。Maven 默认的依赖范围,该范围的依赖对编译,运行,测试不同的classpath 都有效。例如我们项目中的 spring-boot-starter;test: 测试依赖范围。该依赖范围只对测试 classpath 有效,在编译项目或者运行项目的时候,是无法使用此类依赖的。例如我们项目中的 spring-boot-starter-test;provided: 已提供依赖范围。该 Maven 依赖对于编译和测试的 classpath 有效,但是在运行时无效;runtime: 运行时依赖范围。顾名思义,该依赖范围对测试和运行的 classpath 有效,但是在编译时无效;system: 系统依赖范围。该依赖范围与 classpath 的关系与 provided 依赖范围是相同的。但是,在使用时需要谨慎注意,因为此类依赖大多数是与本机绑定的,而不是通过Maven仓库解析出来的,切换环境后,可能会导致依赖失效或者依赖错误。

4.1 排除依赖

传递性依赖可以帮助我们简化项目依赖的管理,但是同时也会带来其他的不必要的风险,例如:会隐式地引入一些依赖,这些依赖可能并不是我们希望引入的,或者这些隐式引入的依赖是 SNAPSHOT 版本的依赖。依赖的不稳定导致了我们项目的不稳定。在我们的项目中,spring-boot-starter-test 依赖中排除了 junit-vintage-engine 依赖是由于我们使用的 springboot 版本是 2.2.6-RELEASE,对应的 Junit 版本是 5.x,但 junit-vintage-engine 依赖中包含了 4.x 版本的 Junit,此时我们就可以将该依赖排除。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions></dependency>在 exclusions 标签中,可以有多个 exclusion 标签,用来排除不需要的依赖。

1.3 使用yarn更新依赖

上文中,我们学习了如何添加依赖,在这里,我们再学习一下如何更新依赖。yarn 更新依赖使用的是 yarn upgrade [package] 命令,这个很简单也很好理解。但是也有一些需要注意得使用点,接下来给大家示范一下。首先我们初始化一个 webpack依赖,指定版本号为3.5.0yarn add webpack@3.5.0此时我们的 package.json 中修改为"dependencies": { "webpack": "3.5.0" }然后我们按照正常的思路,使用 yarn 命令尝试去更新 webpack 依赖yarn upgrade webpack虽然控制台没有任何报错,也提示更新成功,但是我们的 package.json 中的配置还是"dependencies": { "webpack": "3.5.0" }这就是我要说明的注意点:yarn upgrade 是按你指定的版本区间升级的,你可以使用 --latest 参数升级到最新版,无视 package.json 中的版本区间。yarn upgrade webpack --latest"dependencies": { "webpack": "4.43.0" }这样就达到我们想升级依赖到最新版本的目的。现在示例的是一个依赖,如果有多个依赖,想同时升级到最新版本,需要执行如下命令:yarn upgrade-interactive

2.1 添加依赖包

打开项目的 pom.xml 文件,在其中添加如下内容:<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.1</version></dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version></dependency><!-- 数据库驱动包 --><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> <scope>compile</scope></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.13.RELEASE</version> <scope>compile</scope></dependency>Tips:Spring MVC 连接数据库时,需要添加 spring-jdbc 依赖包。

3. Maven 的依赖解析顺序

我们知道了 Maven 通过坐标去仓库中寻找对应的构件,那么这个机制的原理是怎么样的呢?Maven 在寻找需要的依赖的时候,会遵照下面的顺序:如果构件的依赖范围是 system,Maven 会直接从本地的文件系统来解析该构件;根据配置的依赖坐标,在本地仓库中寻找该构件,如果能够搜索到,则解析成功;如果本地仓库没有搜索到,那么就会去已经配置了的远程仓库中搜索该构件,搜索到后,下载到本地仓库中,提供项目使用;如果依赖的版本是 RELEASE 或 LATEST,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/maven-metadata.xml),并且与本地仓库中对应的元数据合并后,计算出真实值,再将其下载到本地仓库中;如果依赖的版本是 SNAPSHOT,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/version/maven-metadata.xml),并且与本地仓库中对应的元数据信息合并后,得到最新的快照版本值,根据这个值去寻找对应的依赖;解析出的快照版本一般是带有时间戳的,下载下来后,会将该时间戳删掉,以无时间戳的形式来使用。

1.2 Npm 的横空出世

作为各种包管理工具中最早出现的开拓者,Npm 是 Node.js 官方提供的,他的出现同时也制定了一些列的包管理规范,如:将所有第三方依赖包放在 node_modules 这个文件目录下,我们在增加,删除,升级依赖也只是更新这个文件下的相关依赖包。增加 package.json 文件,这个文件中存放本项目及项目的依赖和版本信息,这样我们就可以一目了然的了解本项目用到了什么,都是什么版本的,不用多处寻找。在使用依赖时,Node 提供的支持是内置的 require 方法,默认会到这个目录下去检索模块,无需手动指定路径。如此一来,有了 Npm 的加持,JavaScript 从一门不被看好得弱类型语言,发展到了现在可以胜任大型前端项目开发,实现模块化,工程化的前端项目搭建,稳定了前后端分离的发展思路。Npm 已经奠定了前端工程基础,但是追求完美的前端程序员们又基于 Npm 不足的地方,提供了新的完善思路,针对如 Npm 安装包的速度问题,包的版本问题加以改善。所以今天我们要学习的 Yarn 就是用来解决这些问题的。

3.3. 编写 Spring 框架使用的配置文件

坐标有了之后,说明我们的工程中已经引入了 Spring 框架的依赖。小伙伴可以检查下是否正确,点开左侧的 External Libraries 查看一下 。那么看到上面的 jar 包列表,表示 Spring 框架中的基本依赖我们已经成功引入。接下来:既然我们使用的是框架,框架是一个半成品,已经封装好了很多功能提供我们使用,而我们如何让他们工作呢? 这里需要一个和 Spirng 框架通信的桥梁 —Spring 框架的核心配置文件。小提示:文件的名称你们可以随便起,我习惯使用 applicationContext.xml。文件的位置放在哪里呢? maven 工程需要放在 src 下面的 resources 下面,如下图:那么配置文件是空的,不要着急。到底应该配置什么,不是自己臆想猜测的。如果你已经下载了源码,那么解压缩它,打开 docs\spring-framework-reference 目录,打开 core.html 查看官方文档,已经给了说明书你不看,你赖谁? 不知道怎么看?下图告诉你:将上面的实例配置信息拷贝到我们的配置文件中,它只是给了最基本的配置头信息,内容部分 针对 bean 做初始化的部分 需要我们自行填充 。

Maven 的依赖

在上一节中,我们重点介绍了 Maven 的项目对象模型(POM),本节我们重点介绍另一个重要概念–依赖。我们会介绍什么是依赖,以及在我们平时的工作中的最佳实践。

1. 什么是 Maven 仓库

我们先想象一下,如果没有 Maven,我们在开发不同项目的时候,如果需要依赖同一个 jar 包,那么就需要分别在两个不同项目中将这个 jar 包引入进去,对于一个程序员来说,这样的做法显然是不合理的,不仅需要我们手动到处复制,而且会多占用我们的磁盘空间。那这个时候,Maven 仓库就出现了。我们通常把依赖称为构件,每一个构件都有自己唯一的坐标,基于这种模式,我们就可以把这些构件存放在一个指定的位置–Maven仓库当中,然后通过其坐标来寻找该构件。在我们学习或者实际开发过程中,只需要在我们的项目当中声明依赖的坐标,在项目编译的或者打包的过程中,Maven 会自动从仓库中去寻找该构件,这样就不需要我们在本地存储这个依赖了。

4.2 依赖归类

在我们实际的开发过程中,我们可能会需要整合很多第三方框架,在整合这些框架的时候,往往需要在 pom.xml 里面添加多个依赖来完成整合。而这些依赖往往是需要保持相同版本的,在升级框架的时候,都是要统一升级到一个相同的版本。如下图,我们可以看到,在引入 dubbo 框架的时候,我们需要引入两个相关的依赖,而且版本号是相同的,这个时候,我们就可以把对应的版本号提取出来,放到 properties 标签里面,作为一个全局参数来使用。类似于 Java 语言中抽象的思想。这时候,我们可以看到,如果在将来的某一天我们需要升级升级 dubbo 框架对应的版本,只需要修改 properties 中的版本号,就能将所有依赖的版本一起升级。

3.3 第三方依赖包的漏洞问题

我们代码工程里面会引入很多第三方依赖包,整个系统的安全性就像漏斗效应,一旦某个依赖包被发现漏洞,我们的整个系统也等于存在威胁边缘。例如下面常见的一些依赖包structfastjsonhttpclientapache commonsspring等等

1.4 使用yarn删除依赖

使用yarn删除依赖的命令为 yarn remove ,此命令有几个小技巧,给大家介绍一下。从当前项目中删除依赖项:yarn remove lodash一次从所有工作空间中删除一个依赖项:yarn remove lodash --all删除所有以开头的依赖项eslint-:yarn remove 'eslint-*'删除@babel范围内的所有依赖项:yarn remove '@babel/*'删除所有匹配的依赖项react-dom或react-helmet :yarn remove 'react-{dom,helmet}'

4.2 创建空(empty)文件

通常,在开发应用程序时创建的所有文件都是基于模板的。但是,有时您可能需要创建空文件。step1:“Project” 工具栏, 选择目标文件夹 “config”。step2:主菜单 File -> New -> File。step3:在弹出框输入文件名,同样可以指定新文件名的整个目录结构,如果嵌套目录尚不存在,则将创建它们。step4:如果未指定扩展名,则将显示"注册新文件类型关联"对话框。可以将扩展名与其中一个已识别的文件类型相关联。这样在 PyCharm 打开该文件时,就会以你选择文件类型打开文件。step5:点击 “ ok" 按钮,如果在新文件名之前指定了不存在的子目录的名称,则整个结构将在目标目录下创建。

2. 依赖注入案例

2.1概念介绍知识回顾对于依赖注入,我们在第一章第一节已经介绍过,我们回顾一下概念解释上面是我们之前对于依赖注入的一个通俗解释。那么这里再着重强调一下 IOC 控制反转与 DI 依赖注入的关系:IOC 控制反转是将对象实例化的动作交由了 Spring 框架, 它的作用是降低了程序的耦合,不需要我们手动的创建对象,但是程序的耦合性还是存在。对象中肯定会有一些其余对象的引用,那么这种引用就称呼为对象的依赖,而 DI 依赖注入其实 是 IOC 设计思想的一种表现形式。对于 这种属性依赖,我们无需手动赋予,也是讲赋值的动作交给 Spring ,那么这种操作就是 依赖注入。依赖注入方式:第一种方式是通过 xml 配置的方式实现;第二种方式是在属性或者方法上使用注解的方式实现。那么,本章节先带大家体验下 xml 方式实现依赖注入。2.2 工程实现:搭建动作介绍创建一个 maven 工程导入Spring 使用的依赖编写业务层的 Service 和持久层的 Dao java 类编写 Spring 的配置文件创建工程 导入依赖 省略可以参考之前创建过的IOC工程java 代码创建 Servcie 的接口和接口的实现类,代码如下://接口代码public interface UserService { public void deleteById(Integer id);}//实现类代码public class UserServiceImpl implements UserService { private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void deleteById(Integer id) { System.out.println("删除的方法执行"); }}UserDao 接口和实现类代码://dao接口代码public interface UserDao {}//dao实现类代码public class UserDaoImpl implements UserDao {}代码解释: dao的接口和实现类中并没有方法,只是为了测试 作为service中的属性依赖,可以实现由 Spring 完成动态注入。重点来了:spring 的核心配置文件:配置解释:在上面的配置文件中:bean 标签是描述一个被实例化的类 而 property 则表示一类中的属性property 标签中的属性 name 一般我们写成类中的属性名称, 实际上,起决定作用的并不是属性名,下面示例再展示ref 表示当前的属性 是一个引用对象,而引用的是谁呢? ref 中的值 必须是在容器中已经实例化的一个引用对象的唯一标识。value 当前的属性可以直接赋值,所以通过 value 中,填写要赋予的数值即可测试结果代码解释可以看到 我们得到了 service 中的类属性 Userdao 的实例,并且也 得到了 字符串属性 userName的值 zs2.3 property注入属性的解释刚刚我们在上面的示例中 展示了xml依赖属性的注入,也是比较好理解。这里我们强调一下使用的注意事项:如果是 property 属性标签实现属性注入,那么类中必须由配置在 property 标签中 name 属性的 set 方法下面我们测试一下set方法的改变:先讲 service 中 dao 的 set 方法改造如下:public void setDao(UserDao userDao) { System.out.println("执行了set方法 给dao属性赋值"); this.userDao = userDao;}这时候代码中的set方法变成了 setDao 配置文件不变,依然是<property name="userDao" ref="userDao"></property>我们看看会产生什么问题Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'userDao' of bean class [com.wyan.service.UserServiceImpl]: Bean property 'userDao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:247) at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426) at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278) at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266) at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97) at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1646)可以看到异常的堆栈信息 无效的 userDao 属性, userDao 不可以 或者 没有有效的 setter 方法提供。更改xml文件中的 property 标签的 name 属性 为 dao<property name="dao" ref="userDao"></property>测试结果如下:所以我们说 property 中的 name 属性不一定要跟 Java类中的属性名保持一致 而是必须跟 setter 方法的名称一致

3.1 使用 while 循环打印文件的每行

假设文件 test.txt 的内容:wwwimooccom下面使用 readline() 方读取文件的每行并打印:file = open('test.txt')while True: line = file.readline() if line == '': break print(line, end = '')file.close()在第 1 行,以只读方式打开文件 test.txt在第 3 行,调用 readline() 方法读取文件的一行,读取的数据包括换行在第 4 行,如果读取到文件尾部,则返回一个空字符串,此时退出循环在第 6 行,缺省情况下 print 输出时会自动加上换行,因为 readline() 返回的数据会包含换行,因此使用命名参数 end = ‘’ 使 print 输出时不换行运行程序,程序输出如下:wwwimooccom

2.3 添加依赖

注意:mall 项目为一个实例项目,中间可能会存在某些不太合理的地方,我们这里更多的关注项目构建过程。mall-account 项目为用户项目,需要被 mall-order 项目、mall-delivery 项目和 mall-web 项目依赖;mall-order 项目为订单项目,需要被 mall-delivery 项目和 mall-web 项目依赖;mall-commodity 项目为商品项目,需要被 mall-web 模块依赖;mall-delivery 项目为物流项目,需要被 mall-web 项目依赖。我们首先在父工程 mall-aggregate 的 pom.xml 文件中,添加 dependencyManagement 节点元素。<properties> <junit.version>4.11</junit.version></properties><dependencyManagement> <dependencies> <dependency> <groupId>com.mic.tech</groupId> <artifactId>mall-account</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.mic.tech</groupId> <artifactId>mall-commodity</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.mic.tech</groupId> <artifactId>mall-order</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.mic.tech</groupId> <artifactId>mall-delivery</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies></dependencyManagement>然后,依次在各个子工程中,根据子项目之间的依赖关系,添加对应的依赖。在添加完依赖之后,我们可以使用之前安装过的 Maven Helper 插件来生成整个工程的依赖关系图。生成之后的依赖关系图如下:从这个图中,我们可以清楚看到目前 mall 工程各个模块直接的依赖关系。在实际的开发过程中,可以根据生成的依赖关系图来判断是否存在某些没必要引入的依赖,进行依赖优化。

3.1 第一步 集成 Swagger-ui-layer 依赖到项目中

我们都知道,向项目中集成依赖的方式有很多种:我们可以直接把依赖包拷贝到项目中去,也可以通过主流包管理工具将依赖进行统一管理,从而将依赖集成到项目中去,本套课程在开篇时已经说明使用 Maven 包管理工具来构建项目,所以这里关于 Maven 的相关知识不再介绍,有不知道同学可以自己去查一下相关资料。出于方便考虑,上述依赖截图对应下面依赖代码:<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version></dependency><dependency> <groupId>com.github.caspar-chen</groupId> <artifactId>swagger-ui-layer</artifactId> <version>1.1.3</version></dependency>代码解释:上方的依赖为 Swagger 的依赖,下放的依赖为 Swagger-ui-layer 的依赖,同学们可以直接将上述两个依赖直接拷贝到自己项目的 pom 文件中去。在将依赖拷贝到项目的 pom 文件中去后,等待依赖加载完毕即可。

2.3 Spring Boot 打包为 war 并运行

也可以选择将 Spring Boot 打包为 war ,然后放置于 Tomcat 的 webapps 目录下加载运行,接下来我们就详细描述下打包为 war 的过程。首先,在 pom.xml 文件中修改默认的打包方式,显式指定打包方式为 war 。 <groupId>com.imooc</groupId> <artifactId>spring-boot-cors</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-cors</name> <description>Demo project for Spring Boot</description> <packaging>war</packaging>然后,由于 Spring Boot 内置了 Tomcat ,所以我们在打包时需要排除内置的 Tomcat ,这样可以避免内置 Tomcat 和 war 包部署运行的 Tomcat 产生冲突。在 pom.xml 中添加如下依赖即可: <!--打war包时排除内置的tomcat--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>再然后,还需要继承 SpringBootServletInitializer 类并重写 configure 方法,这是为了告诉 Tomcat 当前应用的入口在哪。@SpringBootApplicationpublic class SpringBootCorsApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootCorsApplication.class); } public static void main(String[] args) { SpringApplication.run(SpringBootCorsApplication.class, args); }}最后,即可同样使用 mvn clean package -Dmaven.test.skip=true 命令打包应用了,运行命令后会在 target 目录下生成 war 文件,将该文件放置于 Tomcat 的 webapps 目录下运行即可。

Gradle 多渠道打包

我们在日常开发中多多少少都会遇到多渠道打包的情况。这些版本可能会上传到不同的应用市场,也可能是是线下多渠道推荐。有时候可能不同的渠道使用的资源图片都不一样。古老的做法就是,需要打多少个渠道包拉出多少份代码分支,分别替换对应的资源文件和包名配置信息等。这种做法非常的耗时耗力。Gradle 可以帮我们用一份代码通过配置实现打出所有的渠道包。

4.3 依赖优化

我们再回过头来看一下 Maven Helper 工具所展示的场景我们在这个工具中可以看到我们项目现在引入的所有的依赖,可以看到哪些是我们用到的,哪些是没有用来的,依赖与依赖之间是否存在冲突。如果出现了上述情况,我们就可以通过删除或者依赖排除的方式来将我们不需要的依赖删除掉,从而使我们的项目更简洁。

2.1 buildscript{} 闭包

首先我们先看下上面的buildscript闭包,这个闭包里是配置 Gradle 脚本执行所需要的的依赖,分别是对应 Maven 仓库和构建工具 Gradle 的版本。2.1.1 repositories{} 闭包这个闭包里面主要是配置远程的 Maven 仓库地址。我们看到里面声明了jcenter()和google(),这两个都是 maven 仓库,上面托管了很多开源项目,依赖了这个我们就可以引用上面的开源项目了。比如 Android 中的 V7,V4 包等。2.1.2 dependencies{} 闭包这个闭包我们直接看,就应该能猜到是配置项目构建工具 Gradle 的版本的,classpath 就是声明一个插件 Gradle来构建项目。dependencies虽然是依赖的意思,但是我们这里需要注意:不能将应用程序的依赖放在这里,应用程序的依赖在单独的build.gradle里面。

2.2 查看项目的任务依赖

要查看项目的依赖关系图,我们可以运行以下命令:$ gradle dependencies......省略部分输出.......kaptTestRelease\--- org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.2.51 +--- org.jetbrains.kotlin:kotlin-stdlib:1.2.51 | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.2.51 | \--- org.jetbrains:annotations:13.0 \--- org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.51 +--- org.jetbrains.kotlin:kotlin-stdlib:1.2.51 (*) \--- org.jetbrains.kotlin:kotlin-script-runtime:1.2.51lintChecks - Configuration to apply external lint check jarNo dependencies......省略部分输出.......运行该命令后我们可以在控制台看到项目的整体依赖关系和各个模块的依赖关系图,如上面的部分输出所示。Tips:上面我们运行的命令输出的是整个项目的依赖,有时候我们只需要查查看当前 module 的依赖,那么我们怎么查查看呢?如下,我们输入gradle [module_name]:dependencies,例如我们想要查看 app 模块的依赖,我们可以执行如下命令://查看APP模块的依赖$ gradle app:dependencies

2.2 增加 Spring Security 依赖

首先,我们要将 Spring Boot 环境配置到工程中,也就是在 pom.xml 文件中将当前工程的父级依赖指定为 Spring Boot。此步写法如下,在 pom.xml 文件中增加以下节点信息:<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/></parent>第二步,在配置好父级依赖后,继续在 pom.xml 中增加 Spring Security 依赖「spring-boot-starter-security」。此步写法如下:<dependencies> <!-- 重点依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency></dependencies>第三步,为了让本实例的效果看得见,我们要将它设置成 Web 工程,所以我们需要继续在 pom.xml 文件中添加依赖。此步写法如下:<dependencies> ... <!-- 用于展示认证效果 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></dependencies>

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号