共計 4508 個字符,預計需要花費 12 分鐘才能閱讀完成。
本篇文章給大家分享的是有關如何進行源碼分析 Detect,丸趣 TV 小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著丸趣 TV 小編一起來看看吧。
Detect
該 buildpack 的探測的內容包含:容器,JRE,框架。具體內容在 components.yml 中可以看到:
# Configuration for components to use in the buildpack
containers:
- JavaBuildpack::Container::DistZip
- JavaBuildpack::Container::Groovy
- JavaBuildpack::Container::JavaMain
- JavaBuildpack::Container::PlayFramework
- JavaBuildpack::Container::Ratpack
- JavaBuildpack::Container::SpringBoot
- JavaBuildpack::Container::SpringBootCLI
- JavaBuildpack::Container::Tomcat
# In order to use Oracle JREs instead of OpenJDK, you must comment out the OpenJDK line and uncomment the Oracle line.
# Please see the documentation for more detail.
jres:
- JavaBuildpack::Jre::OpenJdkJRE
# - JavaBuildpack::Jre::OracleJRE
frameworks:
- JavaBuildpack::Framework::AppDynamicsAgent
- JavaBuildpack::Framework::JavaOpts
- JavaBuildpack::Framework::MariaDbJDBC
- JavaBuildpack::Framework::NewRelicAgent
- JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration
- JavaBuildpack::Framework::PlayFrameworkJPAPlugin
- JavaBuildpack::Framework::PostgresqlJDBC
- JavaBuildpack::Framework::SpringAutoReconfiguration
- JavaBuildpack::Framework::SpringInsight
由該文件可以知道該 buidpack 支持的容器,JRE 和框架。當然你可以自己添加。
detect 的入口是 bin/detect,該腳本非常簡單,調用 JavaBuildpack 的 with_buildpack 靜態方法創建實例,然后在代碼塊里調用 JavaBuildpack.detect 方法。最后將 detect 的結果組成一個字符串輸出,如果探測不對,則什么也不輸出。
components = JavaBuildpack::Buildpack.with_buildpack(build_dir, Detect failed with exception %s) do |buildpack| # 這里 with_buildpack 創建了一個 JavaBuildpack::Buildpack 的實例,查看 buildpack.rb 可以看到
buildpack.detect
end.compact
接下來看 JavaBuildpack::Buildpack 類,在 buildpack.rb 中。
with_buildpack 方法
是在 class self 中的,因此它是一個靜態方法,在看方法定義:
def with_buildpack(app_dir, message)
app_dir = Pathname.new(File.expand_path(app_dir)) # app_dir 變成一個 Pathname 實例
application = Component::Application.new(app_dir) # 創建 application 實例
Logging::LoggerFactory.instance.setup app_dir # 初始化日志
yield new(app_dir, application) if block_given? # ** 創建一個對象,并且調用外部給的代碼塊 **
rescue = e
handle_error(e, message)
end
特別注意其中注釋加 ** 的那句,語法比較繞
detect 方法
detect 方法分別對應用使用的容器,JRE,框架探測
def detect
tags = tag_detection(container , @containers, true)
tags.concat tag_detection(JRE , @jres, true) unless tags.empty? # 如果不為空則連接 tags
tags.concat tag_detection(framework , @frameworks, false) unless tags.empty?
tags java-buildpack=#{@buildpack_version.to_s false} unless tags.empty? # 加上 buildpack 版本
tags = tags.flatten.compact.sort
@logger.debug { Detection Tags: #{tags} }
tags
end
detection 方法
調用每個組件的 detect 方法,這些其實是子組件(如:容器大項中的 tomcat 子項),并將結果集合返回。
def detection(type, components, unique)
detected = []
tags = []
components.each do |component|
result = component.detect
next unless result # 如果結果不為空則跳出循環
detected component
tags result
end
fail Application can be run by more than one #{type}: #{names detected} if unique detected.size 1
[detected, tags]
end
具體項目的 detect 方法
這里重點關注下 tomcat 的 detect 方法,tomcat.rb
tomcat 的類定義:
class Tomcat JavaBuildpack::Component::ModularComponent
初始化方法
def initialize(context, version_validator)
super(context, version_validator)
@sub_components = supports? ? sub_components(context) : [] # tomcat 支持嗎?,如果支持,初始化子項目,注意:這里兩個問號,前一個是方法 support? 后一個是問號表達式
end
可以知道 Tomcat 是繼承自 ModularComponent,detect 方法是在 ModularComponent 中定義的,
def detect
supports? ? @sub_components.map(:detect).flatten.compact : nil # 如果支持探測子項目
end
tomcat 的 support? 方法
def supports?
web_inf? !JavaBuildpack::Util::JavaMainUtils.main_class(@application) # WEB-INF 目錄存在,且不存在 Main 方法
private
def web_inf?
(@application.root + WEB-INF).exist? # 其實檢查的是,WEB-INF 目錄是否存在
end
再看子項目有哪些?
def sub_components(context)
[ TomcatInstance.new(sub_configuration_context(context, tomcat)),
TomcatLifecycleSupport.new(sub_configuration_context(context, lifecycle_support)),
TomcatLoggingSupport.new(sub_configuration_context(context, logging_support)),
TomcatAccessLoggingSupport.new(sub_configuration_context(context, access_logging_support)),
TomcatRedisStore.new(sub_configuration_context(context, redis_store)),
TomcatInsightSupport.new(context)
]
end
TomcatInstance 的 detect
先從配置文件 config/tomcat.yml 中找到 tomcat 的版本及下載路徑
tomcat:
version: 8.0.+
repository_root: {default.repository.root}/tomcat
然后從 repository_root(默認是:https://download.run.pivotal.io/) 下載 tomcat/index.yml,該文件包含了所有版本的 tomcat 的下載路徑,找到具體的版本,如:8.0+ 指,8.0 以上的版本,找到了 8.0.14。
需要說明的是:
tomcat 支持之后,TomcatInstance 是默認支持的,因為 tomcat instance 就是基本的 tomcat 包, TomcatLifecycleSupport,TomcatLoggingSupport,TomcatAccessLoggingSupport 也是默認支持的。
如果需要會話共享,復制,設置了 service 環境變量,TomcatRedisStore 則是支持的。
而 TomcatInsightSupport 尚不支持。
以上就是如何進行源碼分析 Detect,丸趣 TV 小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注丸趣 TV 行業資訊頻道。