跳至内容 跳至搜索

延迟加载钩子

LazyLoadHooks 允许 Rails 延迟加载许多组件,从而加快应用程序的启动速度。由于这个特性,现在无需在启动时仅为了应用配置而 `require` ActiveRecord::Base。相反,会注册一个钩子,该钩子会在 ActiveRecord::Base 加载后应用配置。此处以 ActiveRecord::Base 为例,但此功能也可应用于其他地方。

这是一个调用 on_load 方法来注册钩子的示例。

initializer 'active_record.initialize_timezone' do
  ActiveSupport.on_load(:active_record) do
    self.time_zone_aware_attributes = true
    self.default_timezone = :utc
  end
end

ActiveRecord::Base 的所有内容都被评估完毕后,就会调用 run_load_hooksActiveRecord::Base 的最后一行是:

ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)

run_load_hooks 将执行所有通过 on_load 方法注册的钩子。在上例中,它将执行 `initializer` 中的代码块。

注册一个已经运行过的钩子会导致该钩子立即执行。这允许钩子嵌套,以便处理依赖于多个延迟加载组件的代码。

initializer "action_text.renderer" do
  ActiveSupport.on_load(:action_controller_base) do
    ActiveSupport.on_load(:action_text_content) do
      self.default_renderer = Class.new(ActionController::Base).renderer
    end
  end
end
方法
O
R

实例公共方法

on_load(name, options = {}, &block)

声明一个将在 Rails 组件完全加载时执行的代码块。如果组件已加载,则代码块会立即执行。

选项

  • :yield - 将 run_load_hooks 传递给 block 的对象。

  • :run_once - 给定的 block 只会运行一次。

# File activesupport/lib/active_support/lazy_load_hooks.rb, line 60
def on_load(name, options = {}, &block)
  @loaded[name].each do |base|
    execute_hook(name, base, options, block)
  end

  @load_hooks[name] << [block, options]
end

run_load_hooks(name, base = Object)

执行通过 on_loadname 注册的所有代码块,使用 base 作为评估上下文。

ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)

在上例中,它将执行在 ActiveRecord::Base 类中为 :active_record 注册的所有钩子。

# File activesupport/lib/active_support/lazy_load_hooks.rb, line 75
def run_load_hooks(name, base = Object)
  @loaded[name] << base
  @load_hooks[name].each do |hook, options|
    execute_hook(name, base, options, hook)
  end
end