TODO: 待补充
官方文档:https://docs.gradle.org/current/userguide/core_dependency_management.html
1. Overview of Gradle.build
以下是我的理解,不对欢迎指正~
外界引入的包,比如之前我用
group: 'com.hynnet', name:'json-lib', version:'2.4'
引入的json-lib,就是不在external library里的,而是在.gradle这样的cache里。当Gradle Build时,他会从cache(H:.gradle\caches…文件夹)和local file repository(external library)里获取jar包,也就是所谓的artifacts(部件)进行依赖管理,它也有能力从网络中获取maven repo和lvy repo的包,比如json-lib jar在maven repo里就有。
2. Declaring Repositories
3. Declaring Dependencies
官方文档:https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring-dependencies
3.1 What are dependency configuration
3.1.1 Overview:
- 每个dependency都可能有不同的作用域,比如有的用来compile source code,有的在runtime时用到…
- Gradle通过Configuration来体现不同的作用域。我对configuration没有深刻的理解,比如比apply java plugin,then will ”add configuration to represent the various classpaths it needs for source code compilation, executing tests and the like“.
Gradle里,configuration == scope of dependency
顺便问一下,为什么我csdn markdown里mermaid的subgraph用不了😂
的确在gradle.build里看到__compile__和__testCompile__: compile is the group of dependencies you need to build your application while testCompile is a group of dependencies that you need only for testing.
3.1.2 Configuration inheritance and composition
- child configuration继承所有super configuration
example: Junit里的testImplementation configuration继承了google.guava中的implementation configuration
configurations {
// self defined configuration:
smokeTest.extendsFrom testImplementation
}
dependencies {
testImplementation 'junit:junit:4.12'
smokeTest 'org.apache.httpcomponents:httpclient:4.5.5'
}
3.2 Resolvable and consumable configurations
3.2.1 configurations have at least 3 different roles:
- to declare dependencies
- as a consumer, to resolve a set of dependencies to files
- as a producer, to expose artifacts and their dependencies for consumption by other projects (such consumable configurations usually represent the variants the producer offers to its consumers)
3.2.2 Examples:
- declare dependencies
// declare dependencies
configurations {
// declare a "configuration" named "someConfiguration"
someConfiguration
}
dependencies {
// add a project dependency to the "someConfiguration" configuration
someConfiguration project(":lib")
}
- the code above doesn’t tell us anything about the intended consumer of this configuration. In particular, it doesn’t tell us how the configuration is meant to be used.
Let’s say that lib is a Java library: it might expose different things, such as its API, implementation, or test fixtures. (Lib有一些API接口等可供外部使用)- 我理解是,
someConfiguration
__expose__了一些artifacts和dependencies- 因此,我们会发现一些附带的配置,这些configuration明确地声明了用法:
- declare usage: Configurations representing concrete dependency graphs
configurations {
// declare a configuration that is going to resolve the compile classpath of the application
compileClasspath.extendsFrom(someConfiguration)
// declare a configuration that is going to resolve the runtime classpath of the application
runtimeClasspath.extendsFrom(someConfiguration)
}
At this point, we have 3 different configurations with different roles:
someConfiguration
declares the dependencies of my application. It’s just a bucket that can hold a list of dependencies.compileClasspath
andruntimeClasspath
are configurations meant to be resolved: when resolved they should contain the compile classpath, and the runtime classpath of the application respectively.
我理解是,compileClasspath, runtimeClasspath是consumer
, someConfigurationdeclares是producer
,我们也定义了他们之间的依赖关系- A resolvable configuration (eg: compileClasspath/ runtimeClasspath) will extend at least one non-resolvable configuration (and may extend more than one).
- Setting up configurations
On the other end, at the library project side (the producer), we also use configurations to represent what can be consumed.
configurations {
// A configuration meant for consumers that need the API of this component
exposedApi {
// This configuration is an "outgoing" configuration, it's not meant to be resolved
canBeResolved = false
// As an outgoing configuration, explain that consumers may want to consume it
canBeConsumed = true
}
// A configuration meant for consumers that need the implementation of this component
exposedRuntime {
canBeResolved = false
canBeConsumed = true
}
}
- In short, a configuration’s role is determined by the canBeResolved and canBeConsumed flag combinations:
- 我的理解:
be resolved: 作为consumer,我们需要resolve(解决) consumer自身dependency graph里各个component间的关系,最终得到各个artifacts(部件)
be consumed: 作为producer,要被别人用,比如父类
- Configuration roles
Configuration role | can be resolved | can be consumed |
---|---|---|
Bucket of dependencies | false | false |
Resolve for certain usage | true | false |
Exposed to consumers | false | true |
Legacy, don’t use | true | true |
3.3 Different kinds of Dependencies
- Module dependencies:
// groovy
dependencies {
runtimeOnly group: 'org.springframework', name: 'spring-core', version: '2.5'
runtimeOnly(...)
}
- File dependencies:
dependencies {
antContrib files('ant/antcontrib.jar')
externalLibs files('libs/commons-lang.jar', 'libs/log4j.jar')
deploymentTools(fileTree('tools') { include '*.exe' })
}
...
dependencies {
runtimeOnly files('libs/a.jar', 'libs/b.jar')
runtimeOnly fileTree('libs') { include '*.jar' }
}
// every dependency has to define its exact location
it is extremely important to assign a version to the file name
- project dependencies
project(':web-service') {
dependencies {
implementation project(':utils')
implementation project(':api')
}
}
-
Gradle distribution-specific dependencies
- Gradle API dependency
- Gradle TestKit dependency
- Local Groovy dependency
-
Documenting dependencies
…