Spring,使用@Configuration和@Bean注释

时间:2012-10-11 16:20:26

标签: java spring annotations

我有一个代码:

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

    }

3 个答案:

答案 0 :(得分:7)

首先,如果您使用Java配置,则必须像这样实例化您的上下文:

new AnnotationConfigApplicationContext(BeanSample.class)

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

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

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

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

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

答案 1 :(得分:6)

生成的bean
@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");

    }
}

<强>输出:

  

[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]好的

答案 2 :(得分:4)

您的测试应该与@Configuration bean配置一样(您之前使用@Configuration java代码定义了使用上下文xml文件定义的内容)

这将使用BeanSample创建一个应用程序上下文,提供bean配置:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanSample.class);

现在,在@Configuration

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

bean名称是方法名称。因此,方法名称上面是&#34; someBean&#34;,在您的情况下,您的bean名称为&#34; getSomeBean&#34;

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

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