dagger系列之Bazel构建dagger2.29.1解说总经理(根目录下BUILD)分发的任务
前言
现在我个人存在一种理念,当我感觉一件事情很难的时候(未知,困难等原因)。当你确定去解决它,了解它,分步骤解决它其实也就那么回事,这个时候只要有一个清晰的、持之以恒的思路,感觉也就那样。这个时候的难点在于找思路,摸准思路,确定思路。顺着思路去解决反而变得简单。
嗯,有道理,沉思中
上一篇文章
dagger系列(四)之Bazel构建dagger2.29.1解说根目录下BUILD
JSR 330标准注解
JSR-330 是 Java 的依赖注入标准。定义了如下的术语描述依赖注入:
A 类型依赖 B类型(或者说 B 被 A 依赖),则 A类型 称为”依赖(物) dependency”
运行时查找依赖的过程,称为”解析
resolving“依赖 如果找不到依赖的实例,称该依赖是”不能满足的 unsatisfied” 在”依赖注入 dependency
injection”机制中,提供依赖的工具称为”依赖注入器 dependency injector”
javax.injects 包提供了如下5个注解(Inject、Qualifier、Named、Scope、Singleton)和1个接口(Provider)。
1.@Inject
标识某个类中,需要由注入器注入的类成员(被标识的成员称为”可注入的”)。
使用规则
1.可用于注解构造器、字段、方法这些类成员(对成员是静态与否、最好是public的)
2.每个类只能有一个构造器可以被标记可注入;空构造器可以不用@Inject注解。
3.可注入的字段不能为 final 的
4.可注入的方法不能为 abstract 的
注入器的依赖注入顺序:
1.构造器 > 字段 > 方法
2.父类 > 子类
3.一个类的两个可注入字段或其他成员无注入顺序
另外的四个注解对依赖注入进一步进行配置。
2.@Qualifier 和 @Named
其中,@Qualifiery用于创建限定器。限定器是一个自定义的注解,可注解字段或方法的参数,用于限制可注入的依赖的类型。限定器注解必须被 @Qualifier 和 @Retention(RetentionPolicy.RUNTIME) 注解。
// 定义限定器
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Big {
}
// 使用限定器
@Inject
public void foo(@ Big Bar bar) {
// some code
}
@Named 就是一个通过 @Qualifier 定义的限定器。
3.@Scope 和 @Singleton
其中,@Scope 用于创建作用域。作用域是一个自定义的注解,可注解构造器,用于要求注入器对注入的实例的创建方式。比如,是每次构造器被调用就创建一个依赖的实例,还是就创建一个依赖的实例然后重用。作用域注解必须被 @Scope 和 @Retention(RetentionPolicy.RUNTIME) 注解。
@ Singleton 就是一个通过 @Scope 定义的作用域。
4.Provider
Provider 作为另一种提供依赖的定义(有一种是 @Inject 注解),其实例提供 T 类型的实例。与 @Inject 注解相比,其还能:
1.返回的实例可以是多个
2.返回的实例可以是延迟返回的
3.返回的实例来自指定作用域内(例如生成了一个Singleton单例类型实例,其他实例都可以引用该实例)
分经理们做了那些事情:
1.生成了dagger_with_compiler.jar,里面的内容是//java/dagger:core;并且给//java/dagger/internal/codegen:component-codegen插件提供依赖
2.生成了producers_with_compiler.jar,里面的内容包括//java/dagger/producers和dagger_with_compiler.jar里面的内容
3.生成了android.jar内容://java/dagger/android,并且给//java/dagger/android/processor:plugin插件提供依赖
4.生成android-support.jar,包含android.jar和//java/dagger/android/support
5.shaded_android_processor.jar和shaded_grpc_server_processor.jar干啥的,咱也不知道啊,咱也不敢问啊,到了再去看
6.生成了user-docs.jar,里面是Dagger依赖注入API文档信息(这个有点意思,回头我给个小案例可以对比当前的API)
那下面的工作基本上就围绕这些分经理工作了。
分经理之生成target:dagger_with_compiler过程
1.生成com.google.dagger:dagger
这里注意一点,生成的目标名称是dagger_with_compiler,但是并不一定就是dagger_with_compiler.jar(默认是这个),
根目录BUILD中的代码:
java_library(
name = "dagger_with_compiler",
exported_plugins = ["//java/dagger/internal/codegen:component-codegen"],
exports = ["//java/dagger:core"],
)
首先找到java/dagger目录,再找到BUILD,打开找core:
java_library(
name = "core",
srcs = glob(["**/*.java"]),
javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX,
tags = ["maven_coordinates=com.google.dagger:dagger:" + POM_VERSION],
exports = ["@google_bazel_common//third_party/java/jsr330_inject"],
deps = [
"@google_bazel_common//third_party/java/jsr330_inject",
],
)
srcs = glob(["**/*.java"]):当前目录下构建java库
javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX:
在根目录//:build_defs.bzl里找SOURCE_7_TARGET_7 和DOCLINT_HTML_AND_SYNTAX,POM_VERSION版本信息
这里主要是生成文档时用到
这里生成了目标core,这个也是dagger核心类,生成的引用名称为com.google.dagger:dagger:POM_VERSION,我们以dagger:2.29.1为例,看下图:
如上图,版本号另存于META-INF文件夹下;dagger目录下文件夹internal,文件夹multibindings以及其他所有java文件,(下载dagger源码),可以查看也只有文件夹internal,文件夹multibindings目录下没有BUILD(两个文件夹里面的java文件是dagger目录下java文件的引用)
exports和deps:表示依赖于jsr330标准注解
load("//tools:maven.bzl", "pom_file")
pom_file(
name = "pom",
artifact_id = "dagger",
artifact_name = "Dagger",
targets = [":core"],
)
上面这段代码调用了tools目录下maven.bzl的pro_file,用于生成maven的pom.xml文件,如下图所示包含了groupId,artifactId等信息,核心代码 targets = [":core"]
生成一堆java文档,目前还没看出来具体用法,目前还没有该步骤的实践
filegroup(
name = "javadoc-srcs",
srcs = glob(["**/*"]),
)
javadoc_library(
name = "core-javadoc",
srcs = [":javadoc-srcs"],
exclude_packages = ["dagger.internal"],
root_packages = ["dagger"],
deps = ["@google_bazel_common//third_party/java/jsr330_inject"],
)
2.exported_plugins = ["//java/dagger/internal/codegen:component-codegen"],执行插件
该插件依赖于上面的com.google.dagger:dagger。找到java/dagger/internal/codegen的BUILD文件,再找到插件component-codegen,如下是代码,
java_plugin(
name = "component-codegen",
generates_api = 1,
output_licenses = ["unencumbered"],
processor_class = "dagger.internal.codegen.ComponentProcessor",
tags = [
"annotation=dagger.Component;" +
"genclass=${package}.Dagger${outerclasses}${classname}",
"annotation=dagger.producers.ProductionComponent;" +
"genclass=${package}.Dagger${outerclasses}${classname}",
],
deps = [":processor"],
)
总结
涉及bazel部分就这么多,反正给自己看的(有人不小心看到了也无所谓,对说的不对给予纠正,对不不了解bazel肯定可以很好的对dagger进行bazel构建部分的理解),不做深入或者太多探讨,有这些对Dagger理解足以!!!下面我就分析dagger源码了
本文地址:https://blog.csdn.net/foshengtang/article/details/109240797