Diese Seite setzt Wissen aus Grundlagen der Paketentwicklung voraus. Es empfiehlt sich, zunächst die grundlegende Funktionsweise von Service Providern zu verstehen.
Warum Deferred Provider nötig sind
Ein gewöhnlicher Service Provider ruft bei jeder Anfrageregister() und boot() auf. Es ist Verschwendung, Funktionen wie Mail-Versand, Queue oder Cache jedes Mal zu initialisieren, obwohl sie auf vielen Seiten gar nicht gebraucht werden.
Das Interface DeferrableProvider
Illuminate\Contracts\Support\DeferrableProvider ist ein schlichtes Interface mit einer einzigen Methode provides().
Grundlegende Implementierung
Die Implementierung erfolgt in drei Schritten.1
DeferrableProvider implementieren
2
Services in register() binden
Bindungen tragen Sie wie in einem normalen Provider in
register() ein.3
Aus provides() die registrierten Services zurückgeben
provides() muss alle Services zurückgeben, die Sie in register() gebunden haben. Laravel bestimmt anhand dieser Liste, „bei welchem Service dieser Provider zu laden ist”.Funktionsweise des Service-Manifests
Beim Start erzeugt Laravel eine Manifest-Dateibootstrap/cache/services.php. Dort ist die Liste der Services aller Deferred Provider hinterlegt.
Ablauf der internen Verarbeitung
Bedeutung der Methode provides()
Vergessen Sie einen Eintrag inprovides(), wird der betroffene Service nie aufgelöst.
$bindings / $singletons verwenden, listen Sie sie in provides() auf.
Grenzen von Deferred Providern
Deferred Provider eignen sich für Provider, die ausschließlich Bindings im Container registrieren. Provider, die inboot() z. B. Folgendes machen, dürfen nicht deferred werden.
when() — Registrierung per Event-Trigger
Mit der Methodewhen() können Sie den Provider laden lassen, sobald ein bestimmtes Event feuert. Praktisch für Provider, die nur in bestimmten Kontexten (z. B. Job-Verarbeitung) benötigt werden.
Nutzen in der Paketentwicklung
Auch bei Drittanbieter-Paketen tragen Deferred Provider zur Performance der Nutzer-Anwendung bei.Empfohlenes Muster
mergeConfigFrom() prüft intern, ob die Konfiguration gecacht ist. Der Aufruf innerhalb von register() eines Deferred Providers ist daher sicher. Bei gecachter Konfiguration passiert allerdings nichts.Artisan-Commands mit runningInConsole() abtrennen
Command-Registrierung ist nur beim Artisan-Start nötig — trennen Sie sie mit runningInConsole(). Wenn Sie einen Provider deferren, der Commands anbietet, listen Sie die Command-Klassen auch in provides() oder stellen Sie einen separaten Command-Provider bereit.
Verwendung im Laravel-Kern
Viele der Kern-Provider von Laravel sind Deferred Provider. So werden Services, die nicht bei jedem Request gebraucht werden, nicht sofort geladen.
In reinen API-Anwendungen kommt es vor, dass
MailServiceProvider oder BroadcastServiceProvider während eines Requests nie geladen werden.
Entscheidungskriterien für Deferring
Services, die sich zum Deferring eignen
Services, die sich zum Deferring eignen
- Services, die nicht in jedem Request genutzt werden (Mail, Reports, externe API-Clients)
- Services, deren Initialisierung externe Verbindungen oder Dateizugriffe erfordert
- Services mit schweren Objekt-Graphen
- Provider, die nur in der CLI verwendete Commands liefern
Services, die sich nicht zum Deferring eignen
Services, die sich nicht zum Deferring eignen
- Provider, die Routen registrieren (
loadRoutesFromusw.) - Provider, die dauerhaft aktive Middleware oder Exception-Handler registrieren
- Provider, die globale Eloquent-Scopes oder Observer registrieren
- Leichte Services, die in den meisten Requests genutzt werden (Overhead des Deferrings überwiegt)
Verwandte Seiten
Grundlagen der Paketentwicklung
Erläutert die Entwicklung von Laravel-Paketen rund um Service Provider.
Versionskompatibilität von Paketen verwalten
Erläutert Wartungsstrategien für Pakete bei Major-Upgrades von Laravel und PHP.