1

在完成 rails 3 初始化过程时,我发现 Rails::Engine 中定义的所有初始化程序(有 10 个)都多次添加到 Rails::Application 实例中。这意味着这些初始化程序将运行多次。下面是分析: 1. Rails::Application#initializers:

def initializers #:nodoc:           
  Bootstrap.initializers_for(self) +
  super +                           
  Finisher.initializers_for(self)   
end

它将调用 super(Rails::Engine) 方法,定义如下:

def initializers
  initializers = []
  ordered_railties.each do |r|
    if r == self
      initializers += super
    else
      initializers += r.initializers 
    end                              
  end
  initializers
end

从 Rails::Engine#initializers 可以看出,每个引擎(继承自 Rails::Engine 的类)都会为其添加 Rails::Engine 的初始化器,包括 Rails::Application。但是所有其他引擎都包含在 Rails::Application 的 ordered_railties 中,因此它们的初始化程序也被添加到 Rails::Application 的初始化程序中。我们可以得出结论,Rails::Engine 的初始化器被多次添加到 Rails::Application 中。我们可以从控制台信息中看到:

1.9.3p194 :002 > Rails.application.initializers.map(&:name).size
 => 119 
1.9.3p194 :001 > Rails.application.initializers.map(&:name).uniq.size
 => 79

所以 Rails::Engine 中的每个初始化器都被添加到 Rails::Application 的 5 倍。我想知道为什么会这样?有什么特别的原因吗?

4

1 回答 1

0

除了名称之外,初始化器还有其他几个属性:上下文、块等。因此,每当从 Rails::Engine 继承的引擎时,Rails::Engine 的所有初始化器都会添加到具有不同上下文的子引擎中。也就是说,尽管 Rails::Application 中有相同名称的重复初始化程序,但它们确实是不同的初始化程序,将在不同的上下文中运行:

def run(*args)                         
  @context.instance_exec(*args, &block)
end 
于 2013-03-21T09:40:33.803 回答