Ruby on rails 项目启动流程
来源:互联网 发布:程序员 手机壁纸 编辑:程序博客网 时间:2024/05/06 14:00
众所周知,我们可以通过rails s 这个命令来启动一个rails 项目,但是这条命令都干了哪些事呢?抽时间研究了下,同时感谢tomwang1013的博客。当我们输入rails s 这个命令的时候,项目会加载项目bin/rails.rb 这个文件 #!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
通过代码我们可以看到这个文件中定义了一个APP_PATH 即我们的项目文件:config/application.rb,并require了config/boot,boot文件主要是做了bundle的初始化。
然后,我们可以看到这个时候rails/commands(railties-3.2.3/lib/rails/commands.rb)文件被load进来,由于我们传入的command参数为s,也就是server,然后我们看看commands的这个文件的源码对应的部分:
when 'server' # Change to the application's path if there is no config.ru file in current dir. # This allows us to run script/rails server from other directories, but still get # the main config.ru and properly set the tmp directory. Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) require 'rails/commands/server' Rails::Server.new.tap { |server| # We need to require application after the server sets environment, # otherwise the --environment option given to the server won't propagate. require APP_PATH Dir.chdir(Rails.application.root) server.start }
在server 这个方法中我们通过server.start这行代码可以看出最终调用了start这个方法,然后查看下start 这个方法。同时这里面也打印了我们熟悉的控制台信息
def start url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}" puts "=> Call with -d to detach" unless options[:daemonize] trap(:INT) { exit } puts "=> Ctrl-C to shutdown server" unless options[:daemonize] #Create required tmp directories if not found %w(cache pids sessions sockets).each do |dir_to_make| FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make)) end puts 'server start ---' super ensure # The '-h' option calls exit before @options is set. # If we call 'options' with it unset, we get double help banners. puts 'Exiting' unless @options && options[:daemonize] end
这个start 这个方法最终会执行super 这个,super 会调用Rack::Server#start方法:代码
def start &blk if options[:warn] $-w = true end if includes = options[:include] $LOAD_PATH.unshift(*includes) end if library = options[:require] require library end if options[:debug] $DEBUG = true require 'pp' p options[:server] pp wrapped_app pp app end # Touch the wrapped app, so that the config.ru is loaded before # daemonization (i.e. before chdir, etc). wrapped_app daemonize_app if options[:daemonize] write_pid if options[:pid] trap(:INT) do if server.respond_to?(:shutdown) server.shutdown else exit end end server.run wrapped_app, options, &blk end
代码执行到server.run wrapped_app 这行代码。wrapped_app方法最终又会调用Rack::Server#app
def app @app ||= begin if !::File.exist? options[:config] abort "configuration #{options[:config]} not found" end app, options = Rack::Builder.parse_file(self.options[:config], opt_parser) self.options.merge! options app end end
最终app 这个方法会加载项目config 目录下的environment.rb这个文件如:
# Load the Rails application.require File.expand_path('../application', __FILE__)require 'whenever'module ProductConfig DYNAMIC_FIELDS = Hash.newendmodule RestConfig PRODUCT_SERVER = ENV["PHOTO_HOST"] || 'http://localhost:3001/' #CUSTOMER_SERVER = ENV["CUSTOMER_HOST"] || 'http://localhost:3001/' CUSTOMER_SERVER = ENV["CUSTOMER_HOST"] || 'http://localhost:3001/' OA_SERVER = 'http://localhost:3001/' #ELEPHANT_HOST = ENV["ELEPHANT_HOST"] || 'http://www.jiuyunda.net:90/' ELEPHANT_HOST = ENV["ELEPHANT_HOST"] || 'http://localhost:3001/' JXC_HOST = ENV["JXC_HOST"] || 'http://localhost:3001/' SETTLE_HOST = ENV["SETTLE_HOST"] || 'http://localhost:3001/'end# Initialize the Rails application.Rails.application.initialize!
Rails.application.initialize!这行代码我们可以看出
项目的初始化完成。这个时候我们代码就回到Rack::Server#start方法的最后一行 server.run wrapped_app, options, &blk 由于我们没有设定任何参数。通过代码
def server @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options) end def self.default(options = {}) # Guess. if ENV.include?("PHP_FCGI_CHILDREN") # We already speak FastCGI options.delete :File options.delete :Port Rack::Handler::FastCGI elsif ENV.include?("REQUEST_METHOD") Rack::Handler::CGI else begin Rack::Handler::Thin rescue LoadError Rack::Handler::WEBrick end end end
我们可以看到rack 为我们选定了默认的server.一般来说是WEBrick .然后WEBrick启动,打印如下信息
INFO WEBrick 1.3.1 INFO ruby 1.9.3 INFO WEBrick::HTTPServer#start: pid=28371 port=3000
如果安装了其他application server的话打印的信息可能会不同如
Booting Puma=> Rails 4.2.4 application starting in development on http://localhost:3000=> Run `rails server -h` for more startup options=> Ctrl-C to shutdown server"assets end:false"Puma starting in single mode...* Version 3.4.0 (ruby 2.3.0-p0), codename: Owl Bowl Brawl* Min threads: 0, max threads: 16* Environment: development* Listening on tcp://localhost:3000
至此项目的启动已完成。
- Ruby on rails 项目启动流程
- Ruby On Rails -- 开发流程
- 范凯谈Ruby on Rails项目实践
- ruby on rails 项目部署(Nginx + Passenger)
- ruby on rails 项目部署(Nginx + Passenger)
- Ruby on Rails 新建Bolg项目
- ruby on rails 项目部署(Nginx + Passenger)
- 凯谈Ruby on Rails项目实践
- Ruby On Rails 快速创建项目
- Ruby on Rails 项目部署(一)
- ubuntu 下 ruby on rails rails server 服务启动失败
- Ruby on Rails创建项目和服务启动中的一些问题
- Ruby on Rails学习笔记(三 创建Rails项目)
- Ruby on Rails(二) - 初探Ruby on Rails, 搭建一个博客项目并发布(草稿)
- [Ruby On Rails] Action Controller - 控制HTTP 流程
- Ruby & Rails on Rails 進階書單
- ruby on rails新建项目,heroku 部署项目
- ruby and ruby on rails
- 更改web.xml默认欢迎页面。
- PRAGMA AUTONOMOUS_TRANSACTION(自治事务)
- java设计模式进阶_singleton
- 自定义组合控件
- Material Design之TextInputLayout
- Ruby on rails 项目启动流程
- 查找算法
- 基于UDP实现的android局域网视频同步播放
- 第三方支付架构设计之—帐户体系
- 互联网广告作弊的危害,以及如何反作弊
- NOIP 火柴排队
- android如何通过拨号界面打开隐藏界面
- 快速求解趣味题 abcd = (ab + cd)^2
- 建立JDBC-ODBC桥接器报错