gpt4 book ai didi

java - Spring Java 配置相同的 Bean 引用

转载 作者:行者123 更新时间:2023-12-01 14:07:19 24 4
gpt4 key购买 nike

浏览问题 Autowire a bean within Spring's Java configuration我有一个问题。

@Configuration
public class Config {

@Bean
public RandomBean randomBean(){
return new RandomBean();
}

@Bean
public AnotherBean anotherBean(){
return new AnotherBean(randomBean()); // this line
}

}

Spring 如何保证该方法 randomBean()将返回与注入(inject)到 AnotherBean 中的引用相同的引用?

它是通过代理实现的吗?

另一方面,通过提供依赖项作为方法参数来做到这一点很明显:
@Configuration
public class Config {

@Bean
public RandomBean randomBean(){
return new RandomBean();
}

@Bean
public AnotherBean anotherBean(RandomBean randomBean){
return new AnotherBean(randomBean);
}

}

编辑:最后,我发现 Further information about how Java-based configuration works internally 中描述的这种行为话题。

最佳答案

只有一个“randomBean”,因为默认范围是 “单例” .(要强制 Spring 在每次需要时生成一个新的 bean 实例,您应该将 bean 的 scope 属性声明为原型(prototype))

singleton

This scopes the bean definition to a single instance per Spring IoC container (default).

prototype

This scopes a single bean definition to have any number of object instances.



Spring 保证该方法 randomBean()将返回与注入(inject)到 AnotherBean 中的引用相同的引用,使用 代理 .

为了生成代理,Spring 使用了一个名为 的第三方库。 CGLIB .
  • Spring 通过生成 来增强类CGLIB 子类
    与 Spring 容器交互以尊重 bean 范围
    方法的语义。
  • 每个这样的 bean 方法都将在生成的子类中被覆盖,
    如果
    容器实际请求 build 的一个新实例。
  • 否则,对此类 bean 方法的调用用作返回的引用
    到容器,通过名称获取对应的bean。

  • org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor
    // To handle the case of an inter-bean method reference, we must explicitly check the
    // container for already cached instances.

    // First, check to see if the requested bean is a FactoryBean. If so, create a subclass
    // proxy that intercepts calls to getObject() and returns any cached bean instance.
    // This ensures that the semantics of calling a FactoryBean from within @Bean methods
    // is the same as that of referring to a FactoryBean within XML. See SPR-6602.
    if (factoryContainsBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName) && factoryContainsBean(beanName)) {
    Object factoryBean = this.beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
    if (factoryBean instanceof ScopedProxyFactoryBean) {
    // Pass through - scoped proxy factory beans are a special case and should not
    // be further proxied
    }
    else {
    // It is a candidate FactoryBean - go ahead with enhancement
    return enhanceFactoryBean(factoryBean.getClass(), beanName);
    }
    }

    如果你想得到两个不同的 bean,你应该通过 @Scope 更改默认范围。
    @Configuration
    public class Config {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RandomBean randomBean(){
    return new RandomBean();
    }

    @Bean
    public AnotherBean anotherBean(){
    return new AnotherBean(randomBean()); // this line
    }

    }

    关于java - Spring Java 配置相同的 Bean 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44516999/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com