9

我有一个代码:

@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

实际上,我不明白应该使用哪个应用程序上下文来拾取我的 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");

    }
4

3 回答 3

7

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

new AnnotationConfigApplicationContext(BeanSample.class)

其次,@Configuration注解不会从被注解的类中生成一个 bean。只有@Bean方法用于创建 bean。

如果您也想拥有一个BeanSamplebean,则必须创建另一种@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 没有任何关系的普通对象。

于 2012-10-11T16:25:27.530 回答
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");

我用一些完整的例子代替AnnotationConfigApplicationContextClassPathXmlApplicationContext

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] OK

于 2012-10-11T16:35:25.160 回答
4

您的测试应该与@Configurationbean 配置类似(您之前使用上下文 xml 文件定义的内容现在使用您的 @Configuration java 代码定义)

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

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);
于 2012-10-11T16:30:13.583 回答