Railsソース読み(六)アクションコントローラ:Dispactch_ユーザ要求のLIlsにおける処理の流れ(1)

5217 ワード

Railsソース読み(六)アクションコントローラ:Dispactchと次の処理フローユーザ要求のLIlsにおける処理の流れ(1)
--この直後:Railsソース読み(二)_script/server
前の分析小回顧:
ユーザーの要求は、rackのスタックを経て、やっとRAlsのアクションコントローラに着きました。これも一つのrackの実現です。ですから、ActControllerを呼び出すようにお願いします。
 
=アクションコントローラ:Displatchのnewコード:
    # DEPRECATE: Remove arguments, since they are only used by CGI
    def initialize(output = $stdout, request = nil, response = nil)
      @output = output
      build_middleware_stack if @@cache_classes 
    end
ヽoo。ツclasesの役割
 
@cache_clases=true〓〓これはデフォルトですが、develop環境ではfalseに設定されています。
falseに設定すると要求ごとに再読み込みされますか?これは開発環境でとても役に立ちます。
 
ハ2 build_middleware.スターは何をしますか
    private
      def build_middleware_stack
        @app = @@middleware.build(lambda { |env| self.dup._call(env) })
      end
@middlewareは文面からもわかるように、middlewareたちを記憶しています。
@middlewareはMiddlewareStockの一例です。
 
@middlewareの割当コード:
    cattr_accessor :middleware
    self.middleware = MiddlewareStack.new do |middleware|
      middlewares = File.join(File.dirname(__FILE__), "middlewares.rb") 
      middleware.instance_eval(File.read(middlewares))
    end
奄middlewares.rbファイルには固定使用が必要なrackたちが格納されています。
use“Rack:Lock”,:if=>lamband{
  !アクションコントロラー:Base.allowcurrency
)
use「アクションコントロラー:Failsafe」
use lambada{Action Controller:Base.session}
    lambada{ActonController:Base.session}
use「アクションコントローラ:Parames Parsser」
use「Rack:MethodOverride」
use「Rack:Head」
use「アクションコントローラ:Stering Coercion」
同前 @@middlewareはMiddlewareStockの一例であり、この例のbuild方法は一つのrackに戻り、このrackはすでにstack順序を並べたrackである。
    def build(app)
      active.reverse.inject(app) { |a, e| e.build(a) } #            reverse 
    end
各middlewares.rbの中のrackは、次の方法を実行します。
      def build(app)
        if block
          klass.new(app, *build_args, &block)
        else
          klass.new(app, *build_args)
        end
      end 
このような結果は、各middlewares.rbファイルの中のrackが、newの一例として出てくるということです。
 
buildの結果:良いrackスタックを構成して、先にnewのトップで、apは一番下にあります。は、トップの例を返します。
そうします。
    #ActionController::ParamsParser.new .call       :
    def initialize(app)
      @app = app
    end
 
    def call(env) #     
      if params = parse_formatted_parameters(env)
        env["action_controller.request.request_parameters"] = params
      end
      @app.call(env) #     , new      app
    end
このように最後に目的を実現しました。newの時に、次の段階のハンドル@appを持って、先に自分のコードを実行して、最後に@ap.calを実行して、これでフィルタリングの効果を実現しました。この方式はいいですね~~  
 
 
@[email protected](lamda env𞓜self.dup.ucall)ここに入ってきたblockは、stackの一番下に置いてあります。
@appは最終的なrackスタックのハンドルです。
小さな問題があります。selfはinner_です。アプリ=アクションコントローラ:Dispactch.newオブジェクトは、なぜdupですか?
 
newコードを解析しました。次はコールコードを実行するべきです。
=コールのコード:
    def call(env)
      if @@cache_classes
        @app.call(env)
      else
        Reloader.run do
          # When class reloading is turned on, we will want to rebuild the
          # middleware stack every time we process a request. If we don't
          # rebuild the middleware stack, then the stack may contain references
          # to old classes metal classes, which will b0rk class reloading.
          build_middleware_stack
          @app.call(env)
        end
      end
    end
ここではdevelop環境下で、@@cache_classisはクローズして、elseの分岐を歩いて、すべての要求はすべて再びbuild rack-stackです。
要求実行のプロセスは以下の通りです。
一つの要請があったら、コールを実行します。
callを実行すると、buildからrackスタックが出ます。
先に実行する前にrackスタックに入れたrackは、最後にblockを実行します。コードは:self.dup.uコール(env)
    #_call   :
    def _call(env)
      @env = env
      dispatch
    end
ここで初めてメイン操作に入ります。dispatch方法です。
    def dispatch
      begin
        run_callbacks :before_dispatch
        Routing::Routes.call(@env)
      rescue Exception => exception
        if controller ||= (::ApplicationController rescue Base)
          controller.call_with_exception(@env, exception).to_a
        else
          raise exception
        end
      ensure
        run_callbacks :after_dispatch, :enumerator => :reverse_each
      end
    end
ここでは、dispachの本当の操作はRoutingに任せました。:Routes.call(@env) 
 
 
まとめ:
アクションコントローラ:Dispactchというrackのcall操作はどのような操作をしましたか?
󑧙1は配置buildによってロックスタックを出しました。
𞃳2はdevelopの中で、@@cache_classisはfalseで、毎回要求するたびにもう一度rack-stackです。
皬3 dispach操作は、アクションコントローラに渡しました。:Routing:Routes.cal(@env)
 
 
 
===終了======
==          ===
==               ==
を選択します。                    =
𞓜                      |