为啥我总是得到单例bean,即使我使用proxyBeanMethods = false?

Posted

技术标签:

【中文标题】为啥我总是得到单例bean,即使我使用proxyBeanMethods = false?【英文标题】:why I always get singleton bean, even if I use proxyBeanMethods = false?为什么我总是得到单例bean,即使我使用proxyBeanMethods = false? 【发布时间】:2022-01-24 01:31:31 【问题描述】:

现在我正在学习 SpringBoot。真的对@Configuration(proxyBeanMethods = false)的注解感到困惑

我定义了一个如下的配置类,

@Configuration(proxyBeanMethods = false)
public class BeanConfiguration 
    @Bean("User")
    @ConfigurationProperties(prefix = "user2")
    public User getUser()
        return  new User();
    

我认为每个 bean 都会有所不同,因为它在单例模式下不起作用。

但测试代码向我展示了不同的想法。

@SpringBootApplication
public class Boot2InitializrApplication 

    public static void main(String[] args) 

        ConfigurableApplicationContext applicationContext = SpringApplication.run(Boot2InitializrApplication.class, args);

        User user1 = (User)applicationContext.getBean(User.class);
        User user2 = (User)applicationContext.getBean(User.class);

        System.out.println((user1 == user2));   **//here ? always true.  even if I set 'proxyBeanMethods = false' .** 



        BeanConfiguration bean = applicationContext.getBean(BeanConfiguration.class);
        User user3 = bean.getUser();
        User user4 = bean.getUser();
        System.out.println(user3==user4);  //here, it varies when proxyBeanMethods is set true or/false.    

    


为什么我通过applicationContext得到的bean总是在单例模式下工作?

【问题讨论】:

【参考方案1】:

根据reference documentation,这实际上是预期的行为:

指定是否应该代理 @Bean 方法以强制执行 bean 生命周期行为,例如即使在用户代码中直接调用@Bean 方法的情况下,也可以返回共享的单例 bean 实例。

这意味着@Configuration(proxyBeanMethods = false)只有在你直接调用getUser()方法时才有效,因此System.out.println((user1 == user2));总是正确的,因为你不是直接调用@Bean方法而是依靠Spring返回给你需要的 Bean(这将是相同的,因为 Spring 管理的 Bean 默认是单例的)。

关于System.out.println(user3==user4),当你使用@Configuration(proxyBeanMethods = true)时它会是真的,因为这意味着Spring管理的Beans生命周期将被强制执行,因此即使你直接调用getUser()方法,它也会返回相同的Bean。如果你使用@Configuration(proxyBeanMethods = false),它将返回false,因为届时Spring管理的Beans生命周期将不会被强制执行,并且会创建并返回一个全新的User

【讨论】:

太棒了!!! .我对这个注释有误解,现在完全理解了。真的很感激...... 在这种情况下,请考虑支持我的答案,甚至接受它是正确的,这样它就可以“关闭”,其他人也可以从中受益;)谢谢! 知道了,哈哈。现在可以了吗? 非常感谢! ;)

以上是关于为啥我总是得到单例bean,即使我使用proxyBeanMethods = false?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的线性搜索总是返回 false,即使该项目在数组中?

为啥我在使用 RestTemplate 获取数据时总是得到 403? [复制]

为啥我不能使用我的 QML 单例模块?

为啥我可以在没有请求的情况下注入请求范围的 bean?

Spring 为啥默认把bean设计成单例的?

为啥我在使用 CustomListAdapter 时得到不同大小的列表行,即使我尝试为自定义列表行提供特定值