Rails源码阅读(零)_config/boot

不论是script/console 还是 script/server 都会调用前置的文件:config/boot

现在分析一下这个文件的源代码,看看究竟做了哪些工作。

 

config/boot.rb阅读:
# Don't change this file!
# Configure your app in config/environment.rb and config/environments/*.rb

RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)

module Rails
  ... ... 
end

# All that for this:
Rails.boot!
 看这个模块定义之外的代码就首尾两行,比较直观。
Rails模块内容:
#启动,做了两件事
  class << self
    def boot!
      unless booted?
        preinitialize
        pick_boot.run
      end
    end

# 可以在preinitialize这里写一个patch,做些rails启动之前的操作:
    def preinitializer_path
      "#{RAILS_ROOT}/config/preinitializer.rb"
    end

# pick_boot会找是用系统安装的rails还是固化到vender目录的rails
#1 verder的rails加载,3个步骤
  class VendorBoot < Boot
    def load_initializer
      require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
      Rails::Initializer.run(:install_gem_spec_stubs)
      Rails::GemDependency.add_frozen_gem_path
    end
  end
#2 系统安装的rails加载
  class GemBoot < Boot
    def load_initializer
      self.class.load_rubygems #=>require 'rubygems'操作和检查版本
      load_rails_gem #=>gem 'rails', version
      require 'initializer'
    end

# rails 是要用系统安装的,还是vender目录的,启动的时候仅仅有没有这个目录来决定
    def vendor_rails?
      File.exist?("#{RAILS_ROOT}/vendor/rails")
    end

# rails启动之前,如果想做些操作,放在哪里呢
    def preinitializer_path
      "#{RAILS_ROOT}/config/preinitializer.rb"
    end

# rails 启动的时候,知道gem版本么
      def gem_version
        if defined? RAILS_GEM_VERSION
          RAILS_GEM_VERSION
        elsif ENV.include?('RAILS_GEM_VERSION')
          ENV['RAILS_GEM_VERSION']
        else
          parse_gem_version(read_environment_rb)
        end
      end
      private
        def read_environment_rb
          File.read("#{RAILS_ROOT}/config/environment.rb")
        end
  看见了么,只能在environment.rb里申明,如果是自己配置的话,不能在例如development.rb里申明

# EVN在很多地方用到,他在哪里定义的呢(我并没有发现在config里面定义的地方)
    Ok吧,在这里
    irb;Object.const_get('ENV')  或者用这个命令ruby -e 'puts Object.const_get("ENV").inspect'

# 一个设计模式,AcstractClass,父类没有必要非要显式申明一个接口给子类
java等编译型语言需要这么做,因为编译的时候会检查
非编译型语言可以不这么做
但申明的话,会更好看些,利于团队合作
  class Boot
    def run
      load_initializer
      Rails::Initializer.run(:set_load_path)
    end
  end

  class VendorBoot < Boot
    def load_initializer
      require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
      Rails::Initializer.run(:install_gem_spec_stubs)
      Rails::GemDependency.add_frozen_gem_path
    end
  end

最终Rails.boot!做了什么
class Boot
    def run
      load_initializer #选取了自带的rails还是vender的rails
      Rails::Initializer.run(:set_load_path) #这个是关键语句
    end
  end
#run的代码:
Rails::Initializer.run(:set_load_path) #做了什么
    def self.run(command = :process, configuration = Configuration.new) #这里已经new了一个conf
      yield configuration if block_given? #可以修改conf的配置
      initializer = new configuration #new 一个 initializer
      initializer.send(command) #执行command #-->>这里就是要执行:set_laod_path
      initializer
    end
    # set_laod_path的执行作用:
    # Rails::Initializer.run(:set_load_path)
    #
    # This is useful if you only want the load path initialized, without
    # incurring the overhead of completely loading the entire environment.

    # Set the <tt>$LOAD_PATH</tt> based on the value of
    # Configuration#load_paths. Duplicates are removed.
    def set_load_path
      load_paths = configuration.load_paths + configuration.framework_paths
      load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } #移除if it is not dir
      $LOAD_PATH.uniq!
    end
   
    #到底有多少framework:
    def framework_paths
      paths = %w(railties railties/lib activesupport/lib) #3个
     #1个,其实actionpack会加载:action_controller和:action_view
      paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view)

      [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework| #4个
        paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework)
      end

      paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
    end
 

==>>总结: 
require File.expand_path('../../config/boot',  __FILE__)
这个文件执行Rails.boot!,作用:
#1 根据有没有vender的rails,确定了使用rails的路径
#2 初始化了rails的环境路径(load_paths)(configuration.load_paths + configuration.framework_paths)



+
+
+
||
+
+
+

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值