LaravelのFormRequestの仕組みを調べてみたので備忘録。 Laravelのバージョンは11.0.7です。
ServiceProviderでのコールバック関数の設定
ServiceProviderでFormRequestのインスタンス化とバリデーションする処理の追加をしています。
Illuminate\Foundation\Providers\FoundationServiceProvider経由でIlluminate\Foundation\Providers\FormRequestServiceProviderが呼ばれます。
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->afterResolving(ValidatesWhenResolved::class, function ($resolved) {
            $resolved->validateResolved();
        });
        $this->app->resolving(FormRequest::class, function ($request, $app) {
            $request = FormRequest::createFrom($app['request'], $request);
            $request->setContainer($app)->setRedirector($app->make(Redirector::class));
        });
    }
Container::resolving() では $resolvingCallbacks プロパティにコールバック関数がセットされます。
    /**
     * Register a new resolving callback.
     *
     * @param  \Closure|string  $abstract
     * @param  \Closure|null  $callback
     * @return void
     */
    public function resolving($abstract, ?Closure $callback = null)
    {
        if (is_string($abstract)) {
            $abstract = $this->getAlias($abstract);
        }
        if (is_null($callback) && $abstract instanceof Closure) {
            $this->globalResolvingCallbacks[] = $abstract;
        } else {
            $this->resolvingCallbacks[$abstract][] = $callback;
        }
    }
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Container/Container.php#L1163-L1174
Container::afterResolving() では $afterResolvingCallbacks プロパティにコールバック関数がセットされます。
    /**
     * Register a new after resolving callback for all types.
     *
     * @param  \Closure|string  $abstract
     * @param  \Closure|null  $callback
     * @return void
     */
    public function afterResolving($abstract, ?Closure $callback = null)
    {
        if (is_string($abstract)) {
            $abstract = $this->getAlias($abstract);
        }
        if ($abstract instanceof Closure && is_null($callback)) {
            $this->globalAfterResolvingCallbacks[] = $abstract;
        } else {
            $this->afterResolvingCallbacks[$abstract][] = $callback;
        }
    }
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Container/Container.php#L1183-L1194
HTTPリクエスト時のインスタンス化
Container::make() すると Container::resolve() が呼び出されます。
    protected function resolve($abstract, $parameters = [], $raiseEvents = true)
    {
        // ...(省略)...
        $object = $this->isBuildable($concrete, $abstract)
            ? $this->build($concrete)
            : $this->make($concrete);
        // ...(省略)...
        
        if ($raiseEvents) {
            $this->fireResolvingCallbacks($abstract, $object);
        }
        // ...(省略)...
        return $object;
    }
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Container/Container.php#L755-L816
fireResolvingCallbacks() は resolvingCallbacks afterResolvingCallbacks にセットされたコールバックを呼び出します。
    protected function fireResolvingCallbacks($abstract, $object)
    {
        $this->fireCallbackArray($object, $this->globalResolvingCallbacks);
        $this->fireCallbackArray(
            $object, $this->getCallbacksForType($abstract, $object, $this->resolvingCallbacks)
        );
        $this->fireAfterResolvingCallbacks($abstract, $object);
    }
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Container/Container.php#L1236-L1245
resolvingCallbacksでインスタンス化したFormRequestにRequestクラスから値が設定されます。 https://github.com/laravel/framework/blob/11.x/src/Illuminate/Http/Request.php#L439-L472
FormRequestクラスはValidatesWhenResolvedインターフェースを実装しているので、ValidatesWhenResolved::classで設定した処理が呼ばれ、 validateResolved() メソッドが叩かれます。
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Container/Container.php#L1276
validateResolved() は以下のような処理になっています。
    /**
     * Validate the class instance.
     *
     * @return void
     */
    public function validateResolved()
    {
        $this->prepareForValidation();
        if (! $this->passesAuthorization()) {
            $this->failedAuthorization();
        }
        $instance = $this->getValidatorInstance();
        if ($this->isPrecognitive()) {
            $instance->after(Precognition::afterValidationHook($this));
        }
        if ($instance->fails()) {
            $this->failedValidation($instance);
        }
        $this->passedValidation();
    }
fails() => passes() という感じで呼び出され、rulesを使ったバリデーションが行われ、バリデーションエラーは $messages プロパティにセットされます。
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Validation/Validator.php#L436-L483