2012-10-11 17 views
7

Ho un codice:primavera, lavorando con @Configuration e annotazioni @Bean

@Configuration 
public class BeanSample { 

    @Bean(destroyMethod = "stop") 
    public SomeBean someBean() throws Exception { 
     return new SomeBean("somebean name1"); 
    } 


    class SomeBean { 

     String name; 

     public SomeBean(String name) { 
      this.name = name; 
     } 

     public void stop() { 
      System.out.println("stop"); 
     } 
    } 

    public static void main(String[] args) throws Exception { 

     BeanSample beanSample = new BeanSample(); 
     SomeBean someBean1 = beanSample.someBean(); 

     ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
       new String[] {"appContext.xml"}); 

     SomeBean someBean2 = (SomeBean) appContext.getBean("someBean"); 

     if (someBean1 == someBean2) System.out.println("OK"); 

    } 
} 

mi aspetto, una volta che comincio app, il BeanSample.getSomeBean() allora SomeBean si avvia ad essere disponibile ' someBean'.

Bu ora ho un errore: No fagiolo di nome 'someBean' è definito

In realtà, io non capisco che Dot app-contesto dovrei usare per raccogliere i miei fagioli in su?

Circa @Configuration:

Eventuali ragioni, perché dovrei usare @Configuration annotazione qui? (Con questo, il mio IDE mette in evidenza le mie lezioni come se fosse primavera-correlato allora, quindi dovrebbe avere un senso)

- OK: dopo aver ottenuto una risposta il mio codice è simile al seguente:

public static void main(String[] args) throws Exception { 

     AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext(BeanSample.class); 

     SomeBean someBean2 = (SomeBean) appContext.getBean("someBean"); 

     if (someBean2 != null) System.out.println("OK"); 

    } 

risposta

6

in primo luogo, se si utilizza la configurazione di Java, è necessario istanziare vostro contesto come questo:

new AnnotationConfigApplicationContext(BeanSample.class) 

in secondo luogo, l'annotazione @Configuration non fa un chicco di fuori della classe che viene annotato. Solo i metodi @Bean vengono utilizzati per creare bean.

Se si desidera avere un bean BeanSample, è necessario creare un altro metodo @Bean che ne crea uno. Ma poi di nuovo, perché vorresti quello? Penso che la classe @Configuration debba essere utilizzata solo come contenitore di configurazione e non per altro.

In terzo luogo, i nomi di bean predefiniti per @Bean non seguono le convenzioni dei getter di proprietà. I nomi dei metodi vengono utilizzati direttamente, nel senso che nel tuo esempio il bean si chiamerebbe getSomeBean e non someBean. Cambiare il metodo a questo:

@Bean(destroyMethod = "stop") 
public SomeBean someBean() throws Exception { 
    return new SomeBean("somebean name1"); 
} 

Infine, la classe @Configuration non deve essere istanziato. I suoi metodi servono solo allo scopo di creare i fagioli. Spring gestirà quindi il loro ciclo di vita, iniettando proprietà e così via. Al contrario, se istanziate la classe e chiamate direttamente i metodi, gli oggetti restituiti saranno solo oggetti normali che non hanno nulla a che fare con Spring.

+0

Ok, ho cambiato la mia domanda allora. – ses

+0

E ho cambiato la mia risposta. ;) – rolve

+0

ok. Funziona. Ho spostato anche BeanSample - non per essere interno. Inoltre, hai fornito il costruttore predefinito per BeanSample. Cercando di capire perché ho bisogno di: @Configuration quindi .. – ses

4

Il test dovrebbe assomigliare a questo con la configurazione di fagioli @Configuration (quello che avrebbe definito in precedenza utilizzando un file di contesto XML è ora definito utilizzando il codice Java @Configuration)

Questo creerà un contesto applicazione con BeanSample fornire il configurazione di fagioli:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanSample.class); 

Ora, nella vostra @Configuration:

@Bean 
public SomeBean someBean() throws Exception { 
    return new SomeBean("somebean name1"); 
} 

il nome del bean è il nome del metodo ..così sopra il nome del metodo è "someBean", nel tuo caso hai avuto il nome di fagioli come "getSomeBean"

Così per cercare il fagiolo che devi fare:

SomeBean bean = appContext.getBean("someBean", SomeBean.class); 
+0

questa risposta è buona. grazie – ses

6

Il fagiolo prodotto da

@Bean 
public SomeBean getSomeBean() 

avrà il nome di default - e questo è il nome del metodo produttore getSomeBean

Così si possono fare due cose

@Bean 
public SomeBean getSomeBean() {...} 
... 
SomeBean bean = (SomeBean) appContext.getBean("getSomeBean"); 
if (bean != null) System.out.println("OK"); 

o

@Bean(name="someBean") 
public SomeBean getSomeBean() {...} 
... 
SomeBean bean = (SomeBean) appContext.getBean("someBean"); 
if (bean != null) System.out.println("OK"); 

Alcuni esempio completo ho usato AnnotationConfigApplicationContext invece di ClassPathXmlApplicationContext

import java.util.Arrays; 

import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
public class BeanSample { 

    @Bean(name="someBean") 
    public SomeBean getSomeBean() throws Exception { 
     return new SomeBean("somebean name1"); 
    } 

    class SomeBean { 

     String name; 

     public SomeBean(final String name) { 
      this.name = name; 
     } 

     public void stop() { 
      System.out.println("stop"); 
     } 
    } 

    public static void main(final String[] args) throws Exception { 

     AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext(BeanSample.class); 

     BeanSample beanSample = (BeanSample) appContext.getBean("beanSample"); 

     //next time use this to have a look at the beans in the context! 
     System.out.println(Arrays.toString(appContext.getBeanDefinitionNames())); 

     SomeBean bean = (SomeBean) appContext.getBean("someBean"); 
     if (bean != null) System.out.println("OK"); 

    } 
} 

USCITA:

[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalPersistenceAnnotationProcessor, beanSample, org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0, someBean] OK

+0

Perché dovrei usare @Configuration qui? (Ho aggiunto questa domanda al post) – ses

+0

Per marcare questa classe come una che configura il contesto primaverile – Ralph

Problemi correlati