Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    331

    [spring] problema con annotation

    Salve a tutti, sto provando ad usare le annotation in spring e la classi con @Autowired ma sto avendo dei problemi.

    Nel file XML del context ho inserito questo:

    codice:
    <context:component-scanbase-package="com.prove"/>
    e ho le seguenti classi:

    Classe A
    codice:
    package com.prove.prove1
    
    @Component
    Class A {
         
           @Autowired
           B b;
    
           public A() {
                b.faiQuesto();
           }
    }
    Classe B
    codice:
    package com.prove.prove1
    
    import com.prove.prove2.C;
    
    @Service
    Class B {
         
           @Autowired
           C c;
    
           public void faiQuesto() {
                c.faiQuello();
           }
    }
    Classe C
    codice:
    package com.prove.prove2
    
    @Service
    Class C {
         
           public void faiQuello() {
                .............
           }
    }
    Quello che io vorrei � che all'avvio del server (installato su tomcat7) venga avviata la classe A che in cascata utilizzi B e C.
    Quello che invece capita � che all'avvio il costruttore della classe A viene istanziato in automatico ma quando chiamo b.faiQuesto(); ho un null pointer exception; da quello che ho letto con gli @Autowired posso usare delle classi senza istanziarle, � corretto?

    Il tutto funziona, invece, se utilizzo quest'altro sistema:

    Classe A
    codice:
    package com.prove.prove1
    
    @Component
    Class A {
         
           B b;
    
           public A() {
                b = B.getInstance();
                b.faiQuesto();
           }
    }
    Classe B
    codice:
    package com.prove.prove1
    
    import com.prove.prove2.C;
    
    Class B {
         
           C c;
    
           private static B b = null;
    
           public static B getInstance() {
                 if (b == null) b = new B();
                 return b;
           }
    
           public void faiQuesto() {
                c = C.getInstance();
                c.faiQuello();
           }
    }
    Classe C
    codice:
    package com.prove.prove2
    
    Class C {
           private static C c = null;
    
           public static C getInstance() {
                 if (c == null) c = new B();
                 return c;
           }
         
           public void faiQuello() {
                .............
           }
    }
    Al di la di voler imparare ad usare gli @Autowired la gestione con i singleton (che funziona) e' comunque un modo corretto di implementare le classi in un server spring?
    Tra le due soluzioni preferirei cmq approfondire quella con le annotation e gli @Autowired (riuscendo quindi a far funzionare in maniera corretta e pulita il caso 1) ) quindi qualsiasi aiuto sara' ben accetto!

    Grazie in anticipo!
    Sandro
    Ultima modifica di DarthSandr; 03-03-2017 a 20:41

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da DarthSandr Visualizza il messaggio
    codice:
    <context:component-scanbase-package="com.prove"/>
    Piccola nota: non so se è un problema di copia-incolla qui sul forum ma tra scan e base ci va almeno uno spazio, ovviamente.

    Quote Originariamente inviata da DarthSandr Visualizza il messaggio
    codice:
    package com.prove.prove1
    
    @Component
    Class A {
         
           @Autowired
           B b;
    
           public A() {
                b.faiQuesto();
           }
    }
    Questo infatti NON può funzionare. Spring PRIMA istanzia la classe tramite reflection (invocando il costruttore) e POI solo dopo sempre tramite reflection determina che il field b è annotato con @Autowired e quindi a fronte di un oggetto B che deve essere ovviamente tirato su da Spring nel contesto, allora lo "inietta" nel campo b.

    Ma tu b.faiQuesto() lo esegui nel costruttore ... quando il campo b è ancora null (e non può essere diversamente).

    Le soluzioni ovviamente ci sono ma dovresti affrontare un po' meglio il "ciclo" di vita dei bean in Spring.


    Quote Originariamente inviata da DarthSandr Visualizza il messaggio
    Il tutto funziona, invece, se utilizzo quest'altro sistema:

    Classe A
    codice:
    package com.prove.prove1
    
    @Component
    Class A {
         
           B b;
    
           public A() {
                b = B.getInstance();
                b.faiQuesto();
           }
    }
    [....altro....]
    Ok ma questo è completamente l'opposto, insomma è l'anti-Dependency-Injection ... anti-Spring. Cioè proprio quello che con Spring (e altri framework per la DI) NON si vuole e non si deve fare.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    331
    Quote Originariamente inviata da andbin Visualizza il messaggio

    Le soluzioni ovviamente ci sono ma dovresti affrontare un po' meglio il "ciclo" di vita dei bean in Spring.

    Ok ma questo è completamente l'opposto, insomma è l'anti-Dependency-Injection ... anti-Spring. Cioè proprio quello che con Spring (e altri framework per la DI) NON si vuole e non si deve fare.
    Immaginavo, dato che spring è un argomento un pò nuovo hai qualche link da consigliarmi per capire meglio il ciclo di vita dei Bean di spring?

    grazie

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da DarthSandr Visualizza il messaggio
    Immaginavo, dato che spring è un argomento un pò nuovo hai qualche link da consigliarmi per capire meglio il ciclo di vita dei Bean di spring?
    C'è la Reference ufficiale (vedi da qui) ma non è un "tutorial", nel senso che non è una guida passo-passo per chi inizia. Poi comunque trovi articoli sparsi in giro per la rete.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    331
    Cercando su internet ho provato questa soluzione che funziona.
    Praticamente, sempre usando le annotation, ho modificato la classe A nel seguente modo:

    codice:
    package com.prove.prove1
    
    @Configuration
    Class A {
         
           @Autowired
           B b;
    
           @PostConstruct
           public void run(){
                b.faiQuesto();
           }
    }
    E in questo modo quello che voglio implementare funziona: all'avvio del server viene chiamato il metodo run() e non ho più i problemi di null pointer e il giro funziona usando le annotation e non i metodi GetInstance() che, come giustamente mi hai fatto notare, vanno contro il concetto della dependency injection.
    Per quello che ho capito di spring in questa configurazione all'avvio del server, spring istanzia tutti i beans coinvolti (io li sto gestendo tramite annotation ma ho visto che si può agire tramite file XML di configurazione) in modo che siano disponibili senza doverli istanziare esplicitamente, è corretto quello che sto dicendo?
    Essendo spring un argomento nuovo, mi preme capire se questa soluzione è concettualmente corretta al di la del suo funzionamento.

    P.S: ho notato però che il costruttore di A viene istanziato due volte all'avvio del server, c'è qualche altro accorgimento da adottare?
    Ultima modifica di DarthSandr; 04-03-2017 a 14:59

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    @Configuration rappresenta il nuovo modo (si chiama Java configuration) per configurare i bean in Spring ed è in pratica la controparte di quello che si fa/faceva nel "vecchio" modo tramite gli XML.
    Una classe @Configuration quindi contiene metodi annotati con @Bean che sono praticamente l'equivalente del <bean> a livello XML.

    La documentazione ed esempio la vedi qui
    Se non era questo il tuo interesse, allora non devi usare @Configuration.

    Riguardo il @PostConstruct sì, questo avviene DOPO che Spring ha istanziato e configurato (=assegnato le dipendenze) il bean.

    Non so esattamente cosa volevi fare ma .... va bene ed è ok che ci sia una fase di inizializzazione particolare per certi bean, però nelle web application non è che si fanno metodi di inizializzazione che vanno a fare chissà quali operazioni lunghe o complesse. Non è una applicazione "standalone" ....
    Se è una webapp, allora "esporrà" qualcosa: pagine web, web service REST o altro. Quindi a monte di tutto ci sono tipicamente i "Controller" che ricevono le richieste e sono loro a far fare "qualcosa" al resto dei bean.

    P.S. continua a studiare Spring, hai appena scalfito i 2 cm della punta del iceberg mentre invece l'iceberg è alto 1000 metri.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    331
    Grazie della risposta.
    Nel mio caso l'applicazione è mista e ha bisogno di avere sia una componente che viene avviata quando l'app parte (nel mio caso si mette in ascolto su Firebase) sia dei controller accessibili come una normale webapp.
    Nell'esempio che ho riportato, per intenderci, B si mette in ascolto su Firebase.
    Uno dei Controller potrebbe a sua volta chiamare B per scrivere/leggere da Firebase on demand e quindi ho bisogno che Firebase sia ovviamente attivo (ma al di la di quello l'applicazione deve avere una componente "standalone" che interagisce con Firebase anche se non viene implicitamente chiamata da un Controller).
    Ultima modifica di DarthSandr; 04-03-2017 a 17:55

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 © 2025 vBulletin Solutions, Inc. All rights reserved.