当我在rails 3初始化过程中工作时,我发现rails::Engine中定义的所有初始化器(一共有10个)都不止一次地被添加到rails::Application实例中。这意味着这些初始化函数将运行多次。分析如下:1. Rails:应用程序初始化:
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#初始化器中看到,每个引擎(从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倍。我想知道为什么会这样?有什么特别的原因吗?
除了名称,初始化器还有其他几个属性:context, block等。因此,每当从Rails:: engine继承一个引擎时,所有Rails:: engine的初始化式都被添加到具有不同上下文的子引擎中。也就是说,虽然在Rails::Application中有相同名称的重复初始化器,但它们确实是不同的初始化器,将在不同的上下文中运行:
def run(*args)
@context.instance_exec(*args, &block)
end