Domanda

In caso di modello di progettazione proxy , qual è la differenza tra Dynamic Proxy JDK e terze parti Dynamic Generation API s come cglib ?

Qual è la differenza tra l'utilizzo di entrambi gli approcci che quando si preferisce uno su un altro?

È stato utile?

Soluzione

JDK Dynamic Proxy può solo proxy per interfaccia (quindi la classe di destinazione deve implementare un'interfaccia, che viene quindi implementata anche dalla classe proxy).

cglib (e javassist) può creare un proxy dalla sottoclassamento.In questo scenario il proxy diventa una sottoclasse della classe target.Non c'è bisogno di interfacce.

Allora Java Dynamic Proxys può proxy: public class Foo implements iFoo dove cglib può proxy: public class Foo

Modifica:

Dovrei menzionare che poiché Javassist e Cglib utilizzano proxy mediante la sottoclassamento, che questo è il motivo per cui non è possibile dichiarare metodi finali o rendere la finale della classe quando si utilizzano frameworks che si basano su questo.Ciò impedirebbe a queste biblioteche di consentendo di sottoclasse la tua classe e sovrascrivere i tuoi metodi.

Altri suggerimenti

Differenze in funzionalità

    .
  • I proxy JDK consentono di implementare qualsiasi set di interfacce durante la sottoclassificazione Object. Qualsiasi metodo di interfaccia, plusObject::hashCode, Object::equals e Object::toString viene quindi inoltrato a un InvocationHandler . Inoltre, viene implementata l'interfaccia della libreria standard java.lang.reflect.Proxy.

  • cglib consente di implementare qualsiasi set di interfacce durante la sottoclassamento della classe non finale. Inoltre, i metodi possono essere sovrascritti opzionalmente, cioè non tutti i metodi non astratti devono essere intercettati. Inoltre, ci sono diversi modi di implementare un metodo. Offre anche una classe InvocationHandler (in un pacchetto diverso), ma consente inoltre di chiamare i metodi super utilizzando intercettori più avanzati come ad esempio un MethodInterceptor. Inoltre, cglib può migliorare le prestazioni da intercettazioni specializzate come FixedValue. Una volta ho scritto un riassunto di diversi intercettori per cglib . < / p>

    Differenze di prestazione

    Proxy JDK sono implementati piuttosto ingenuamente con un solo dispatcher di intercettazione, il InvocationHandler. Ciò richiede un metodo virtuale in una spedizione a un'implementazione che non può essere sempre in linea. Cglib consente di creare codice di byte specializzato Cosa può a volte migliorare le prestazioni. Ecco alcuni confronti per l'implementazione di un'interfaccia con 18 metodi stub:

                cglib                   JDK proxy
    creation    804.000     (1.899)     973.650     (1.624)
    invocation    0.002     (0.000)       0.005     (0.000)
    
    .

    Il tempo è notato in nanosecondi con deviazione standard in parentesi graffe. Puoi trovare maggiori dettagli sul benchmark in Byte Buddy's Tutorial , dove Byte Buddy è un'alternativa più moderna a cglib. Inoltre, notare che cglib non è più in uno sviluppo attivo.

Proxy dinamico: Implementazioni dinamiche delle interfacce in runtime utilizzando JDK API di riflessione .

Esempio: Spring utilizza i proxy dinamici per le transazioni come segue:

 Inserisci la descrizione dell'immagine qui

Il proxy generato viene sopra il fagiolo. Aggiunge un comportamento transnazionale al fagiolo. Qui il proxy genera dinamicamente in fase di esecuzione utilizzando API di riflessione JDK.

Quando un'applicazione viene fermata, il proxy verrà distrutto e avremo solo interfaccia e fagioli sul file system.


.

Nell'esempio sopra abbiamo un'interfaccia. Ma nella maggior parte dell'attuazione dell'interfaccia non è il migliore. Quindi il bean non implementa un'interfaccia, in tal caso, usiamo l'ereditarietà:

 Inserisci la descrizione dell'immagine qui

Per generare tali proxy, la primavera utilizza una biblioteca di terze parti chiamata cglib .

cglib ( c ode g energia lib rary) è integrata in cima a ASM , questo è utilizzato principalmente il fagiolo generato proxy proxy e aggiunge il comportamento del bean nei metodi proxy.

Esempi per JDK Dynamic Proxy e cglib

primavera ref

dalla documentazione di primavera :

.

Spring AOP utilizza i proxy dinamici JDK o il cglib per creare il proxy per un dato oggetto bersaglio. (I proxy dinamici JDK sono preferiti Ogni volta che hai una scelta).

Se l'oggetto bersaglio da presentare implementa almeno un'interfaccia Quindi verrà utilizzato un proxy dinamico JDK. Tutte le interfacce Implementato dal tipo di destinazione sarà provocato. Se l'oggetto bersaglio Non implementa alcuna interfaccia, verrà creata un proxy cglib.

Se si desidera forzare l'uso del proxying cglib (ad esempio, al proxy Ogni metodo definito per l'oggetto bersaglio, non solo quelli implementati dalle sue interfacce) puoi farlo. Tuttavia, ci sono alcuni problemi a Considera:

I metodi finali non possono essere consigliati, in quanto non possono essere sovrascriviti.

Avrai bisogno dei binari di cglib 2 sul tuo classpath, mentre Dynamic I proxy sono disponibili con il JDK. La primavera ti avverterà automaticamente Quando ha bisogno di cglib e le classi della biblioteca di cglib non si trovano sul classpath.

Il costruttore del tuo oggetto proxied verrà chiamato due volte. Questo è un Conseguenza naturale del modello proxy cglib in cui una sottoclasse è Generato per ogni oggetto proxied. Per ogni istanza proxied, due Gli oggetti vengono creati: l'oggetto proxed effettivo e un'istanza del sottoclasse che implementa il consiglio. Questo comportamento non è esposto quando si utilizzano proxy JDK. Di solito, chiamando il costruttore del il tipo proxied due volte, non è un problema, come di solito ci sono solo Assegnazioni che si svolgono e nessuna logica reale è implementata nel Costruttore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top