Java 为什么这个bean不是空的

Java 为什么这个bean不是空的,java,spring,Java,Spring,下面的代码在Spring4中运行良好,但我想知道为什么getBean(FooService.class)返回一个已经加载的bean。我认为bean加载的顺序没有保证,这意味着有可能得到一个空bean。是因为加载目标是一个类而不是一个字符串(即对象),还是因为FooService bean有一个特殊的作用域,比如prototype?如果是这样,getBean(类)和getBean(对象)之间的区别是什么 首先,String是一个完整的权限类,就像您可以自己创建的任何类一样 在fooService中

下面的代码在Spring4中运行良好,但我想知道为什么getBean(FooService.class)返回一个已经加载的bean。我认为bean加载的顺序没有保证,这意味着有可能得到一个空bean。是因为加载目标是一个类而不是一个字符串(即对象),还是因为FooService bean有一个特殊的作用域,比如prototype?如果是这样,getBean(类)和getBean(对象)之间的区别是什么


首先,String是一个完整的权限类,就像您可以自己创建的任何类一样

在fooService中获得某些内容的原因是ApplicationContext能够根据传递给它的参数检索托管bean

如果无法检索bean,则可能会出现以下一些异常:

抛出:NoSuchBeanDefinitionException-如果没有给定类型的bean 找到NonuniqueBeandDefinitionException-如果 找到给定类型BeansException-如果无法找到该bean 创造


ApplicationContext::getBean
方法创建指定类型的bean(如果尚未创建)

对于以下两个bean类:

@Component
public class Bean1 {

    @Autowired
    private ApplicationContext applicationContext;

    public Bean1() {
        System.out.println("Bean 1 constructor");
    }

    @PostConstruct
    public void init() {
        System.out.println("Bean 1 @PostConstruct started");
        applicationContext.getBean(Bean2.class);
        System.out.println("Bean 1 @PostConstruct completed");
    }
}

@Component
public class Bean2 {

    @Autowired
    private ApplicationContext applicationContext;

    public Bean2() {
        System.out.println("Bean 2 constructor");
    }

    @PostConstruct
    public void init() {
        System.out.println("Bean 2 @PostConstruct started");
        applicationContext.getBean(Bean1.class);
        System.out.println("Bean 2 @PostConstruct completed");
    }
}
上下文初始化期间的打印输出为:

Bean 1 constructor
Bean 1 @PostConstruct started
Bean 2 constructor
Bean 2 @PostConstruct started
Bean 2 @PostConstruct completed
Bean 1 @PostConstruct completed

对于不同的
getBean
方法,如果传入一个类,那么该类的一个bean必须正好出现在应用程序上下文中(否则Spring不会告诉您需要该类的多个bean实例中的哪一个),而通过名称搜索允许您获取特定的命名bean实例。

我认为这是spring不获取null对象的感觉。实际上,我认为您的bean是null的,我的意思是,您使用applicationContext来加载特定的bean对象。有了春天,你就不需要它了。您可以在bean参数上使用@Autowired annotation,或者在bean作为参数的类构造函数中,或者在set方法中更好地使用@Autowired annotation。您是否可以找到一个官方文档支持“@PostConstruct方法,该方法在创建所有bean之后调用。”根据它的注释,postConstruct在构造这个bean之后立即被调用。我认为,每个bean都是一个接一个地构建的。因此,请提供更多的证据:)@Tiina您似乎是对的,不能保证此时已经创建了未显式自动连接的bean。我编辑了我的答案,但是如果一个bean还没有被初始化,也就是说,没有加载到上下文中,并且这个bean的初始化时间比FooService bean早呢。通过这种方式,getBean将返回null。applicationContext.getBean(…)与(at)Autowired一样,spring将确保在找到其定义时返回一个bean,这是真的吗?实际上,Autowired更好,因为使用注释意味着更低的耦合。
Bean 1 constructor
Bean 1 @PostConstruct started
Bean 2 constructor
Bean 2 @PostConstruct started
Bean 2 @PostConstruct completed
Bean 1 @PostConstruct completed