2012-10-11 140 views
7

我有一個代碼:春天,@Configuration和@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"); 

    } 
} 

我預計,一旦我開始應用,在BeanSample.getSomeBean(),然後SomeBean開始可用的「 someBean」。

卜現在我有一個錯誤:無豆名爲「someBean」被定義

其實,我斑點不明白其中的應用程序上下文應該使用來接我的豆子呢?

關於@Configuration

任何原因,我爲什麼要在這裏使用@Configuration註解? (這一個,我的IDE凸顯我的課,因爲它是那麼Spring相關的,所以它應該是有意義)

- OK:後我得到的回答我的代碼看起來像這樣:

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

    } 

回答

6

首先,如果你使用Java的配置,你必須實例化您的上下文是這樣的:

new AnnotationConfigApplicationContext(BeanSample.class) 

二,@Configuration批註不使bean出被註釋之類的。只有@Bean方法用於創建bean。

如果您還想要一個BeanSample bean,則必須創建另一個創建一個的方法@Bean。但是,再一次,你爲什麼要這麼做?我認爲一個@Configuration類應該只用作配置容器,而不是其他任何東西。

第三,@Bean的默認bean名稱不遵循屬性獲取器的約定。方法名稱直接使用,這意味着在您的示例中,bean將被命名爲getSomeBean而不是someBean。將方法更改爲:

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

最後,@Configuration類不應該實例化。其方法僅用於創建bean的目的。 Spring將處理它們的生命週期,注入屬性等等。相反,如果您實例化類並直接調用方法,則返回的對象將只是與Spring沒有任何關係的普通對象。

+0

好的,我改變了我的問題。 – ses

+0

我改變了我的答案。 ;) – rolve

+0

好的。有用。我也移動BeanSample - 不是內在的。此外,還提供了BeanSample的默認構造函數。試圖理解爲什麼我需要:@Configuration然後.. – ses

4

你的測試看起來應該像這樣與@Configuration bean的配置(你會使用上下文xml文件已經定義當前使用的是@Configuration Java代碼中定義)

這將創建BeanSample提供的應用程序上下文bean的配置:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanSample.class); 

現在,在您的@Configuration

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

的bean名稱是方法名稱..因此該方法的名字上面是​​「someBean」,你的情況,你有豆名稱爲「getSomeBean」

所以查找你所要做的豆:

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

這個答案也不錯。 thx – ses

6

通過

生產的豆
@Bean 
public SomeBean getSomeBean() 

將有默認名稱 - 這是製作方法的名稱getSomeBean

所以,你可以做兩件事情

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

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

一些完整的例子我用AnnotationConfigApplicationContext代替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

爲什麼我應該在這裏使用@Configuration? (我已將此問題添加到帖子中) – ses

+0

爲了將此類標記爲配置春天上下文的類 – Ralph