eager_autoload加载方式在一些开发中很是常见,先举个例子:
module MyClass
extend ActiveSupport::Autoload
eager_autoload do
autoload :Cache
end
end
使用场景中可以直接在 App 启动的时候执行:
MyClass.eager_load!
在production环境下,我们只需在config.ru下配置:
Rails.application.eager_load!
下面我们来分析下源码看看上面到底干了什么:
module Autoload
def self.extended(base) # :nodoc:
base.class_eval do
@_autoloads = {}
@_under_path = nil
@_at_path = nilƒ
@_eager_autoload = false
end
end
def autoload(const_name, path = @_at_path)
unless path
full = [name, @_under_path, const_name.to_s].compact.join("::")
path = Inflector.underscore(full)
end
if @_eager_autoload
@_autoloads[const_name] = path
end
super const_name, path
end
def eager_autoload
old_eager, @_eager_autoload = @_eager_autoload, true
yield
ensure
@_eager_autoload = old_eager
end
def eager_load!
@_autoloads.each_value { |file| require file }
end
好我们来分析下吧:
第一步: 在上面的类中我们调用了这个eager_autoload方法,传入了一个代码块
def eager_autoload
old_eager, @_eager_autoload = @_eager_autoload, true
yield
ensure
@_eager_autoload = old_eager
end
这个方法就是把@_eager_autoload改为true了,然后执行代码块中的autoload方法,这个方法的具体执行请看:
http://blog.csdn.net/baodongdong123/article/details/75736079
具体不分析了, 我们把其中的一部分拿出来:
if @_eager_autoload
@_autoloads[const_name] = path
end
上面已经把@_eager_autoload=true,所以这个方法会执行,上面的类执行结果:
@_autoloads = {Cache: "my_class/cache"}
然后我们在项目启动的时候调用了eager_load!方法
def eager_load!
@_autoloads.each_value { |file| require file }
end
这个方法就比较简单了,直接把@_autoloads中的值进行require,这个值其实就是路劲,也就把一些需要的加载进来了。
思考:对比下autoload和eager_autoload有什么区别嘛?
其实我们在分析autoload的时候并没有直接require,具体干了什么是ruby的autoload做的,并没有直接加载进来
而eager_autoload这里我们看到require了,其实直接加载进来了,直接初始化了,rails中app下的文件在启动的时候都加载进来了采用的就是eager方式,要不然用户体验多差,不可能用户请求的时候才吧需要的加载进来这样会影响性能。