AbstractApplicationContext(Spring)下refresh()方法的用途是啥?为啥使用 refresh() 后 bean 单例范围丢失?

Posted

技术标签:

【中文标题】AbstractApplicationContext(Spring)下refresh()方法的用途是啥?为啥使用 refresh() 后 bean 单例范围丢失?【英文标题】:What is the usage of refresh() method under AbstractApplicationContext (Spring)? Why is the bean singleton scope lost after using refresh()?AbstractApplicationContext(Spring)下refresh()方法的用途是什么?为什么使用 refresh() 后 bean 单例范围丢失? 【发布时间】:2020-04-11 07:08:50 【问题描述】:

已使用以下代码检查 AbstractApplicationContext 下的 refresh() 方法的工作情况。但是发现由于刷新beans单例范围丢失了。对调用单例后究竟发生了什么感到困惑。

使用的代码:

public static void main(String[] args) 
        @SuppressWarnings("resource")
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

        HelloWorld obj1 = (HelloWorld) context.getBean("helloWorld");
        obj1.setMessage("Object 1...");
        obj1.getMessage();

        context.refresh();
        obj1.getMessage();

        HelloWorld obj2 = (HelloWorld) context.getBean("helloWorld");
        obj2.getMessage();

        context.refresh();

        obj1.getMessage();
        obj2.getMessage();
    

XML 配置:

<bean id="helloWorld" class="com.vinaymitbawkar.HelloWorld"
        init-method="init" destroy-method="destroy">
</bean>

输出:

init method
Your Message : Object 1...
destroy method
init method
Your Message : Object 1...
Your Message : null
destroy method
init method
Your Message : Object 1...
Your Message : null

为什么会这样?为什么这里失去了单例作用域而obj2返回null?

【问题讨论】:

答案是否有问题,因为您不接受它? 没有马可。答案没有错。您的回答清除了我的查询。谢谢你。 :) 【参考方案1】:

refresh 的文档说:

加载或刷新配置的持久化表示, 可能是 XML 文件、属性文件或关系数据库 架构。

这是一种相当复杂的说法,即刷新实际上是从您的 .xml 文件或 java 配置加载或重新加载您的应用程序上下文/bean 配置。如果有帮助,请将其视为创建“新”应用程序上下文。

因此,您的示波器不会“丢失”。相反,您有一个重新加载的 appcontext,它会返回一个“新”单例 bean,它没有设置消息。因此你得到了空值。

【讨论】:

以上是关于AbstractApplicationContext(Spring)下refresh()方法的用途是啥?为啥使用 refresh() 后 bean 单例范围丢失?的主要内容,如果未能解决你的问题,请参考以下文章