【发布时间】: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
我问这个问题是因为我有以下假设
当spring容器初始化一个bean时,它的默认作用域是Singleton
spring 容器应该只使用一个 bean 实例
此外
ApplicationContext扩展BeanFactory(间接)我们可以交替使用
BeanFactory和ApplicationContext
我的问题是关于基础的,spring 容器为 beanFactory 和 ApplicationContext 分别加载两个单独的实例是否正确?
【问题讨论】:
-
弹簧单例是每个上下文的单例,因为您正在创建 2 个上下文,您将获得 2 个 bean 实例。此外,您不应该在该地方创建应用程序上下文,您应该创建一次并在需要 bean 实例时使用依赖注入。