【问题标题】:Spring loads two different instances when loaded with BeanFactory and ApplicationContext with a single spring.xml file使用单个 spring.xml 文件加载 BeanFactory 和 ApplicationContext 时,Spring 会加载两个不同的实例
【发布时间】:2015-05-31 10:24:17
【问题描述】:

我正在编写一些代码来研究从 Spring 容器中获取 bean 的不同方法。为了解决我遇到的问题,我保持代码非常简单。

我已经写了下面的类

三角形类

package org.studyspring.beanfactory;
public class Triangle {
    public String draw() {
        return "Triangle Drawn";
    }
}

Spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id ="triangle" class ="org.studyspring.beanfactory.Triangle"/>
</beans>

测试类

package org.studyspring.beanfactory;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;

import static org.junit.Assert.assertEquals;

public class BeanFactoryTest {
private static BeanFactory factory;
private static ApplicationContext context;

    @BeforeClass
    public static void setupBeforeClass(){
        factory = new XmlBeanFactory(new FileSystemResource("./basicSpring/src/test/resources/spring.xml"));
        context= new ClassPathXmlApplicationContext("spring.xml");
    }

    @Test
    public void getTriangleBean_WithBeanFactory(){
        Triangle triangle = (Triangle) factory.getBean("triangle");
        String message = triangle.draw();
        assertEquals("Triangle Drawn",message);
    }

    @Test
    public void getTriangleBean_WithApplicationContext(){
        Triangle triangle = (Triangle) context.getBean("triangle");
        String message = triangle.draw();
        assertEquals("Triangle Drawn",message);
    }

    @Test
    public void triangleBean_ShouldBeSame_WithApplicationContextAndWithBeanFactory(){
        Triangle triangle = (Triangle) factory.getBean("triangle");
        Triangle triangle1 = (Triangle) context.getBean("triangle");
        String message = triangle.draw();
        assertEquals(triangle,triangle1);
    }
}

我认为我的测试用例 triangleBean_ShouldBeSame_WithApplicationContextAndWithBeanFactory 应该已经通过,但实际上它失败了,并出现以下错误

Expected :org.studyspring.beanfactory.Triangle@22c1609b
Actual   :org.studyspring.beanfactory.Triangle@45ad71f0

我问这个问题是因为我有以下假设

  1. 当spring容器初始化一个bean时,它的默认作用域是Singleton

  2. spring 容器应该只使用一个 bean 实例

  3. 此外ApplicationContext 扩展BeanFactory(间接)

  4. 我们可以交替使用BeanFactoryApplicationContext

我的问题是关于基础的,spring 容器为 beanFactory 和 ApplicationContext 分别加载两个单独的实例是否正确

【问题讨论】:

  • 弹簧单例是每个上下文的单例,因为您正在创建 2 个上下文,您将获得 2 个 bean 实例。此外,您不应该在该地方创建应用程序上下文,您应该创建一次并在需要 bean 实例时使用依赖注入。

标签: java spring


【解决方案1】:

这是因为您创建了 2 个不同的容器。您可以制作 2 个 ApplicationContexts

ApplicationContext context1;
ApplicationContext context2;

其中仍然会有两个不同的 Triangle 实例

【讨论】:

  • 如果我有两个不同的类需要这个 bean,那么如果我在两个类的 ApplicationContext 的帮助下获得 bean,那么我们将获得新构建的 bean 吗?这意味着如果我们修改一个 bean 的属性,它们将不会在其他类中可见?
  • 不是 2 个不同的类,而是同一类的 2 个不同实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多