Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269

    [Spring] cosa rappresenta un bean in spring framework

    Salve,

    ragazzi, qualcuno può spiegarmi semplicemente cosa rappresenta un Bean nel framework Spring?

    Grazie anticipatamente.
    Con i sogni possiamo conoscere il futuro...

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da gaten Visualizza il messaggio
    cosa rappresenta un Bean nel framework Spring?
    Un bean in Spring alla fin fine è semplicemente un oggetto che viene creato (istanziato) da Spring a fronte del nome della classe (se usi la configurazione XML) e possibilmente anche configurato da Spring se necessario.

    Ma alla fine è un oggetto come un altro .... solo che: a) è contenuto, cioè tenuto referenziato, in un "contenitore" che è gestito da Spring e b) insieme ad altri oggetti è eventualmente coinvolto in tutto il discorso della Dependency Injection.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Un bean in Spring alla fin fine è semplicemente un oggetto che viene creato (istanziato) da Spring a fronte del nome della classe (se usi la configurazione XML) e possibilmente anche configurato da Spring se necessario.

    Ma alla fine è un oggetto come un altro .... solo che: a) è contenuto, cioè tenuto referenziato, in un "contenitore" che è gestito da Spring e b) insieme ad altri oggetti è eventualmente coinvolto in tutto il discorso della Dependency Injection.
    intanto grazie per la tua risposta.

    ti posso chiedere un esempio?

    Inoltre quando dici che è coinvolto con il discorso della Dipendency Injection, in che senso?
    Cioè che posso avere constructor injection o metodi di setter injection nei miei oggetti bean?

    Aggiungo:
    Dalla definizione di bean, mi sembra di capire che sono oggetti istanziati e gestiti all'internto di un container. Com'è composto questo container?
    Ultima modifica di gaten; 17-03-2017 a 17:50
    Con i sogni possiamo conoscere il futuro...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da gaten Visualizza il messaggio
    ti posso chiedere un esempio?

    Inoltre quando dici che è coinvolto con il discorso della Dipendency Injection, in che senso?
    Un concetto fondamentale alla base di Spring è la Dependency Injection. Questa tecnica sostanzialmente inverte ciò che si farebbe normalmente per assegnare delle dipendenze (cioè altri oggetti necessari) ad un certo oggetto.

    Lo scenario senza DI è questo. Immagina una classe A che ha bisogno di una classe B per poter fare qualcosa. Questo è un codice basilare:

    codice:
    package com.esempio;
    
    public class A {
        private B b;
    
        public A() {
            b = new B();
        }
    
        public void faiQualcosaConB() {
            // qui usa b
        }
    }
    codice:
    package com.esempio;
    
    public class B {
        // .......
    }

    Fin qui nulla di strano, è puro e normalissimo codice Java. Però vedi bene quella istanziazione nel costruttore:

    b = new B();

    C'è qualcosa di male? Di per sé no, nel senso che è il minimo da fare e in contesti piccoli/normali può anche andare bene. La questione è che qui è la classe A che si sta preoccupando di ottenere le dipendenze, in questo caso solo un oggetto B. Un oggetto di un'altra classe lo si può ottenere in vari modi: se ha un costruttore pubblico, invocandolo. Se la classe fosse un "singleton", avrebbe il costruttore privato e offrirebbe un es. getInstance() statico pubblico per cui si farebbe b = B.getInstance();
    O in altri modi. Il succo non cambia: è la classe A che ha del codice interno per creare/ottenere le dipendenze di cui ha bisogno.

    In progetti e contesti di un certo livello però questo fatto pone diversi problemi.

    E se io volessi testare il comportamento della classe A? Testerei ed eseguirei implicitamente anche quello che fa la classe B. Ma immagina che B faccia accesso ad un DB. Se io testo la classe A, NON voglio che si vada realmente su un DB. Vorrei che la classe A avesse un oggetto B "fittizio" che non va realmente su DB ma risponda alle richieste come voglio io, potendo simulare un successo, un errore o altro.
    Peccato che non si può. La classe A fa new B(), questo è il problema. Questo è cablato nel codice di A e non lo puoi cambiare così su due piedi.

    E se volessi che in base ad una certa configurazione esterna, invece di un oggetto B si possa usare una sua sottoclasse BPlus ? Idem non si può. A istanzia un B e non "sa" nulla di BPlus.


    Con la DI invece lo scenario cambia: NON è più A che si preoccupa di ottenere le dipendenze ma è "qualcun'altro" che dà ad A le dipendenze. Come? Banalmente tramite un costruttore o un metodo "setter". Chiaramente la classe A deve essere scritta per facilitare e permettere la DI.

    Nell'esempio, basta cambiare A in:

    codice:
    package com.esempio;
    
    public class A {
        private B b;
    
        public A(B b) {
            this.b = b;
        }
    
        public void esegui() {
            // qui si usa b
        }
    }

    Anche qui è normalissimo codice Java, che si potrebbe anche usare con altro normale codice Java:

    B unB = new B();
    A unA = new A(unB);


    Ma in questo caso non c'è alcuna DI fatta da un framework con un suo contenitore. Ripeto, fin qui è normalissimo e comunissimo codice Java.

    Quote Originariamente inviata da gaten Visualizza il messaggio
    Cioè che posso avere constructor injection o metodi di setter injection nei miei oggetti bean?
    Sì, appunto ... ci sto arrivando.

    Con Spring puoi avere un file XML (qui metto solo la parte dei bean, ma serve anche tutta la dichiarazione standard XML iniziale):

    codice:
    <bean id="unA" class="com.esempio.A">
      <constructor-arg ref="unB"/>
    </bean>
    
    <bean id="unB" class="com.esempio.B"/>

    In questo modo Spring: istanzia prima B (capisce che è una dipendenza per A), poi istanzia A usando il costruttore che riceve l'oggetto B. L'oggetto A potrebbe poi essere tirato fuori dal container esplicitamente oppure iniettato a sua volta in un altro oggetto.

    Alla fine è tutto qui, come concetto.

    Quote Originariamente inviata da gaten Visualizza il messaggio
    Com'è composto questo container?
    A livello interno, proprio materialmente, non lo so. È sicuramente una "mappa" nel senso di associazione, perché in Spring ciascun bean è associato ad un nome (una stringa, è quel id) e opzionalmente a N "alias".
    Ultima modifica di andbin; 18-03-2017 a 01:15
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269
    Grazie mille, ora mi � tutto pi� chiaro.
    Se possibile, vorrei capire il discorso legato al testing...
    Quote Originariamente inviata da andbin Visualizza il messaggio
    E se io volessi testare il comportamento della classe A? Testerei ed eseguirei implicitamente anche quello che fa la classe B. Ma immagina che B faccia accesso ad un DB. Se io testo la classe A, NON voglio che si vada realmente su un DB. Vorrei che la classe A avesse un oggetto B "fittizio" che non va realmente su DB ma risponda alle richieste come voglio io, potendo simulare un successo, un errore o altro.
    Peccato che non si pu�. La classe A fa new B(), questo � il problema. Questo � cablato nel codice di A e non lo puoi cambiare cos� su due piedi.
    Mi sembra di capire che nel primo caso (senza DI), non sono propenso ad avere "scaffolding", nel senso che ho un new B(), per cui , testando la classe A, devo istanziare obbligatoriamente un oggetto B. Nel secondo caso(dove ho DI), posso invece avere scaffolding, costruendo un caso particolare passando al costruttore di A un oggetto B o (sottoclasse di B), a meno che non uso un'interfaccia che potrebbe senz'altro aiutarmi a rendere il tutto ancora pi� riusabile.
    Con i sogni possiamo conoscere il futuro...

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Innanzitutto se si usano interfacce di "astrazione" (ad esempio per i Dao) è sicuramente e certamente meglio dal punto di vista del design generale. Perché puoi: a) realizzarne più implementazioni (se/come necessario), b) puoi creare più facilmente oggetti "mock", fittizi per i test.

    La questione del testing è facile da comprendere con un classico esempio: una classe di Service (con della logica applicativa) usa un certo Dao per accedere ad una tabella su DB. Se io voglio testare la logica del Service, NON voglio che si vada realmente su DB!
    Per poter evitare questo deve essere possibile "staccare" il vero Dao e assegnare al Service un altro oggetto (che con una interfaccia a monte è quindi più facile "spacciarlo" per quello vero). Questo oggetto però deve essere fittizio e ci sono librerie apposite di mocking come Mockito e altre per questo. Un oggetto di questo tipo è fittizio perché non è quello reale ma è creato dalla libreria di mocking che ha tutta una infrastruttura per poter "instrumentare" l'oggetto per fagli fare quello che vuoi.

    Tutto questo viene più facile da fare se c'è la DI facendo in modo che una implementazione del Dao venga "iniettata" dal container. Quindi quando la applicazione gira realmente, verrà iniettato il "vero" Dao che accede su DB. Mentre quando vengono lanciati i test, ci sarà una apposita configurazione di Spring che crea e inietta un Dao fittizio per i test.

    Senza DI è meno facile, sicuramente è molto difficile se il Service non offre alcun appiglio per poter cambiare la implementazione del Dao dall'esterno.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.