Spring,使用@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’的bean

实际上,我不明白我应该用哪种应用程序上下文来挑选我的咖啡豆?

关于@Configuration

有什么理由,为什么我应该在这里使用@Configuration注释? (有了这个,我的IDE突出了我的类,因为它与Spring相关,所以它应该有意义)

好的:在我得到答案后,我的代码看起来像这样:

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

首先,如果使用Java配置,则必须实例化上下文,如下所示:

 new AnnotationConfigApplicationContext(BeanSample.class) 

其次, @Configuration注释不会使注释的类中的bean成为可能。 只有@Bean方法用于创建bean。

如果你想拥有一个BeanSample bean,你必须创建另一个创建一个的@Bean方法。 但话又说回来,你为什么要这样呢? 我认为@Configuration类只应该用作配置容器而不能用于其他任何东西。

第三,@ Bean的默认bean名称不遵循属性getter的约定。 方法名称是直接使用的,在您的示例中,bean将被命名为getSomeBean而不是someBean 。 将方法更改为:

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

最后,不应该实例化@Configuration类。 它的方法仅用于创建bean。 然后Spring将处理它们的生命周期,注入属性等等。 相反,如果您实例化类并直接调用方法,则返回的对象将只是与Spring无关的普通对象。

生产的豆子

 @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

您的测试应该与@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”,在您的情况下,您将bean名称设置为“getSomeBean”

所以要查找你必须要做的bean:

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