Skip to main content
I service provider registrati all’avvio di Laravel vengono caricati a ogni richiesta, anche se le loro funzionalità non vengono mai usate. I deferred service provider risolvono questo problema: rinviano il caricamento finché il servizio non viene effettivamente richiesto.
Questa pagina presuppone la conoscenza delle basi dello sviluppo di pacchetti. Ti consigliamo di leggere prima le nozioni di base sui service provider.

Perché servono i deferred provider

I service provider normali chiamano register() e boot() a ogni richiesta. Inizializzare ogni volta funzionalità che non vengono usate in tutte le pagine — come invio email, code o cache — è uno spreco.
Rendendolo differito, verrà inizializzato solo nelle richieste che generano realmente un report.

L’interfaccia DeferrableProvider

Illuminate\Contracts\Support\DeferrableProvider è un’interfaccia semplice con un solo metodo: provides().
Basta implementarla e il provider passa in modalità differita.

Implementazione di base

L’implementazione di un deferred provider si articola in tre passi.
1

Implementare DeferrableProvider

2

Registrare i servizi in register()

Come in un provider normale, i bind vanno in register().
3

Restituire i servizi registrati da provides()

provides() deve restituire tutti i servizi registrati in register(). Da questa lista Laravel decide “quando richiedere quale servizio caricare questo provider”.

Meccanismo del service manifest

All’avvio Laravel genera un file manifest chiamato bootstrap/cache/services.php. In esso è memorizzata la lista dei servizi forniti dai deferred provider.
Grazie a questo manifest, Laravel sa “quale provider fornisce quale servizio” senza dover caricare i file. I provider vengono caricati solo alla prima risoluzione del servizio.
Se aggiungi o modifichi provider, rigenera il manifest.

Flusso del funzionamento interno


Importanza del metodo provides()

Se in provides() manca una registrazione, quel servizio non verrà mai risolto.
Lo stesso vale per le proprietà $bindings / $singletons: vanno anch’esse elencate in provides().

Limitazioni dei deferred provider

I deferred provider sono adatti quando l’unico scopo è registrare binding nel container. Non si può differire un provider che in boot() fa cose come queste.
Puoi scrivere il metodo boot() in un deferred provider, ma il suo contenuto non verrà eseguito finché il servizio non viene risolto. Mettere in boot() operazioni “sempre necessarie” come rotte e middleware porta a comportamenti imprevisti.

Metodo when() — registrazione via trigger evento

Con il metodo when() puoi registrare il provider al verificarsi di eventi specifici. Utile per provider necessari solo in contesti specifici, come l’elaborazione dei job.
Se l’evento restituito da when() viene emesso, il provider viene caricato anche se il servizio non è stato risolto direttamente.

Utilizzo nello sviluppo di pacchetti

Anche nella distribuzione come pacchetto di terze parti, i deferred provider contribuiscono alle performance dell’applicazione dell’utente.

Pattern consigliato

mergeConfigFrom() verifica internamente se la configurazione è in cache, quindi può essere chiamato in sicurezza dentro register() di un deferred provider. Se la configurazione è già in cache, non fa nulla.

Isolare la registrazione dei comandi Artisan con runningInConsole()

La registrazione dei comandi serve solo all’avvio di Artisan, quindi usa un branch con runningInConsole(). Se il provider che fornisce i comandi è differito, ricorda di includere le classi dei comandi in provides() oppure predisponi un provider dedicato ai soli comandi.

Esempi nel core di Laravel

Molti dei provider core di Laravel sono differiti. Il design è pensato per evitare di caricare in modo immediato tutti i servizi che non vengono usati a ogni richiesta. In un’applicazione fatta solo di endpoint API può capitare che MailServiceProvider o BroadcastServiceProvider non vengano mai caricati durante una richiesta.

Criteri per decidere se differire

  • Servizi non usati in tutte le richieste (mail, report, client di API esterne, ecc.)
  • Servizi la cui inizializzazione richiede connessioni esterne o letture di file
  • Servizi con grafi di oggetti pesanti
  • Provider che offrono comandi usati solo da CLI
  • Provider che registrano rotte (con loadRoutesFrom, ecc.)
  • Provider che registrano middleware o exception handler sempre attivi
  • Provider che registrano global scope o observer Eloquent
  • Servizi leggeri usati nella maggior parte delle richieste (l’overhead del deferring sarebbe maggiore)

Pagine correlate

Nozioni di sviluppo dei pacchetti

Come sviluppare pacchetti Laravel imperniati sui service provider.

Gestire la compatibilità tra versioni dei pacchetti

Strategie di manutenzione dei pacchetti per gli upgrade major di Laravel e PHP.
Ultima modifica il 13 luglio 2026