2012-10-11 15 views
7

Ich habe einen Code:Spring, die Arbeit mit @Configuration und @Bean Anmerkungen

@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"); 

    } 
} 

Ich erwarte, wenn ich app starten, wird die BeanSample.getSomeBean(), dann wird SomeBean Gestartet von zur Verfügung stehen ' etwasBean '.

Bu jetzt habe ich einen Fehler: Keine Bean mit dem Namen ‚someBean‘ definiert ist

Eigentlich verstehe ich Punkt nicht die app-Kontext sollte ich meine Bohnen abholen verwenden?

Über @Configuration:

Irgendwelche Gründe, warum sollte ich @Configuration Anmerkung hier verwenden? (Mit diesem, meine IDE hebt meine Klassen, wie es Frühling bezogene waren dann, so sollte es Sinn machen)

- OK: nachdem ich eine Antwort bekam mein Code wie folgt aussieht:

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"); 

    } 

Antwort

6

Erstens, wenn Sie die Java-Konfiguration verwenden, haben Sie Ihren Kontext wie folgt instanziiert:

new AnnotationConfigApplicationContext(BeanSample.class) 

Zweitens, die @Configuration Annotation nicht eine Bohne aus der Klasse machen, die mit Anmerkungen versehen ist. Nur die Methoden @Bean werden zum Erstellen von Beans verwendet.

Wenn Sie auch eine BeanSample Bean haben möchten, müssen Sie eine andere @Bean Methode erstellen, die eine erstellt. Aber warum willst du das noch? Ich denke, die Klasse sollte nur als Konfigurationscontainer und nicht für irgendetwas anderes verwendet werden.

Drittens folgen die Standard-Bean-Namen für @Bean nicht den Konventionen der Eigenschaft Getter. Die Methodennamen werden direkt verwendet, dh in Ihrem Beispiel würde die Bean getSomeBean heißen und nicht someBean. Ändern Sie die Methode dazu:

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

Schließlich ist die @Configuration Klasse sollte nicht instanziert werden. Ihre Methoden dienen nur dem Zweck, die Bohnen zu erzeugen. Spring wird dann ihren Lebenszyklus behandeln, Eigenschaften injizieren und so weiter. Wenn Sie dagegen die Klasse instanziieren und die Methoden direkt aufrufen, sind die zurückgegebenen Objekte nur normale Objekte, die nichts mit Spring zu tun haben.

+0

Ok, ich habe meine Frage dann geändert. – ses

+0

Und ich habe meine Antwort geändert. ;) – rolve

+0

ok. Es klappt. Ich habe auch BeanSample verschoben - nicht um inner zu sein. Außerdem haben Sie den Standardkonstruktor für BeanSample bereitgestellt. Versuchen zu verstehen, warum ich brauche: @Configuration dann .. – ses

4

Ihr Test wie diese mit @Configuration Bean Konfiguration aussehen soll (was man vorher einen Kontext XML-Datei definiert hat jetzt definiert Ihren @Configuration Java-Code verwenden)

Dies wird einen Anwendungskontext erstellen mit BeanSample der Bereitstellung bean-Konfiguration:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanSample.class); 

nun in Ihrem @Configuration:

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

der Bean-Name ist der Methodenname ..so über dem Methodennamen ist „someBean“, in Ihrem Fall, dass Sie den Bean-Namen als „getSomeBean“ hatten

So die Bohne Sie tun müssen, sehen:

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

Diese Antwort ist auch gut. thx – ses

6

Die Bohne produziert von

@Bean 
public SomeBean getSomeBean() 

den Standardnamen haben - und das ist der Name des Herstellers Methode getSomeBean

So kann man zwei Dinge tun

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

oder

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

Einige komplettes Beispiel habe ich AnnotationConfigApplicationContext statt 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"); 

    } 
} 

OUTPUT:

[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

Warum sollte ich @Configuration hier verwenden? (Ich habe diese Frage dem Beitrag hinzugefügt) – ses

+0

Um diese Klasse als eine zu markieren, die den Federkontext konfiguriert – Ralph

Verwandte Themen