两个 class 中的自动装配 Bean 在从第二个 class 访问后未更新
Autowired Bean in two classes not being updated after accessing it from the second class
我有以下场景:
一个 bean 在两个 class 中自动装配,我在一个 class 中填充了 bean,然后我检查了第二个 class 中的 bean,它没有被填充。然而,当我在填充 bean 的 class 中添加一个 getter 并调用 getter 时,它 returns 填充了 bean。为什么我不能在另一个 class 中直接访问那个 bean,因为它在 spring 上下文中充当单例,所以不应该填充它吗?
JUnit4 测试 class 从 xml 文件加载 spring 上下文:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/spring/test-main-context.xml" })
public class MyTests {
@Autowired
MyObject myObject;
@Autowired
MyUtils myUtils;
@Test
public void testingContext() {
myUtils.setMyObjectFromDB();
System.out.println(myUtils.getMyObject().getId());
System.out.println(myObject.getId());
}
}
MyUtils:
public class MyUtils {
@Autowired MyObject myObject;
public void setMyObjectFromDB() {
MyObject myDBObject = new MyObject();
//
// getting myObjectFromDB;
//
myObject = myDBObject;
}
public MyObject getMyObject() {
return myObject;
}
}
在测试中 class,myUtils.getMyObject().getId()
returns 一个正确的 id 但第二行 myObject.getId()
它 returns null.
为什么在 MyUtils class 中设置的 MyObject 在两个 classes 中都是 @Autowired 当我在测试中直接访问它时没有更新 class.
当您在 setMyObjectFromDB
方法中重新分配 myObject = myDBObject;
时,您正在创建一个新对象并将其引用保存在 myObject
变量中,这与使用 Autowired
.
当你使用Autowired
时,它会在变量中分配创建的bean的引用。但是,如果您重新分配该变量,它将指向新对象。
编辑:
如果你真的需要用Autowired
初始化更新myObject
的所有变量,最好创建一个存储myObject
变量的容器class。
public class MyObjectContainer {
@Autowired
MyObject myObject;
// Getters & Setters
}
在所有 classes 中,您要自动装配 myObject
,请改用 MyObjectContainer
class 的对象。当您想要更新 myObject
值时,只需在 myObjectContainer
对象中将其更新为 setter。所以你的 MyUtils
会是这样的:
public class MyUtils {
@Autowired MyObjectContainer myObjectContainer;
public void setMyObjectFromDB() {
MyObject myDBObject = new MyObject();
//
// getting myObjectFromDB;
//
myObjectContainer.setMyObject(myDBObject);
}
public MyObjectContainer getMyObjectContainer() {
return myObjectContainer;
}
}
查看代码,MyObject
没有注入两个 class 中的任何一个。你得到的印象是它是在 MyUtils
class 中注入的,因为你实际上是在 setter 方法中手动创建的。
问题是为什么 MyObject
没有注入,可能有很多原因,其中之一是您没有在 MyObject
中定义 @Component
class 或者它不在您的组件扫描路径中,方法是在您的 Spring 应用程序 class 中添加 @ComponentScan(basePackages = "put-your-base-package-name")
。
我有以下场景:
一个 bean 在两个 class 中自动装配,我在一个 class 中填充了 bean,然后我检查了第二个 class 中的 bean,它没有被填充。然而,当我在填充 bean 的 class 中添加一个 getter 并调用 getter 时,它 returns 填充了 bean。为什么我不能在另一个 class 中直接访问那个 bean,因为它在 spring 上下文中充当单例,所以不应该填充它吗?
JUnit4 测试 class 从 xml 文件加载 spring 上下文:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/spring/test-main-context.xml" })
public class MyTests {
@Autowired
MyObject myObject;
@Autowired
MyUtils myUtils;
@Test
public void testingContext() {
myUtils.setMyObjectFromDB();
System.out.println(myUtils.getMyObject().getId());
System.out.println(myObject.getId());
}
}
MyUtils:
public class MyUtils {
@Autowired MyObject myObject;
public void setMyObjectFromDB() {
MyObject myDBObject = new MyObject();
//
// getting myObjectFromDB;
//
myObject = myDBObject;
}
public MyObject getMyObject() {
return myObject;
}
}
在测试中 class,myUtils.getMyObject().getId()
returns 一个正确的 id 但第二行 myObject.getId()
它 returns null.
为什么在 MyUtils class 中设置的 MyObject 在两个 classes 中都是 @Autowired 当我在测试中直接访问它时没有更新 class.
当您在 setMyObjectFromDB
方法中重新分配 myObject = myDBObject;
时,您正在创建一个新对象并将其引用保存在 myObject
变量中,这与使用 Autowired
.
当你使用Autowired
时,它会在变量中分配创建的bean的引用。但是,如果您重新分配该变量,它将指向新对象。
编辑:
如果你真的需要用Autowired
初始化更新myObject
的所有变量,最好创建一个存储myObject
变量的容器class。
public class MyObjectContainer {
@Autowired
MyObject myObject;
// Getters & Setters
}
在所有 classes 中,您要自动装配 myObject
,请改用 MyObjectContainer
class 的对象。当您想要更新 myObject
值时,只需在 myObjectContainer
对象中将其更新为 setter。所以你的 MyUtils
会是这样的:
public class MyUtils {
@Autowired MyObjectContainer myObjectContainer;
public void setMyObjectFromDB() {
MyObject myDBObject = new MyObject();
//
// getting myObjectFromDB;
//
myObjectContainer.setMyObject(myDBObject);
}
public MyObjectContainer getMyObjectContainer() {
return myObjectContainer;
}
}
查看代码,MyObject
没有注入两个 class 中的任何一个。你得到的印象是它是在 MyUtils
class 中注入的,因为你实际上是在 setter 方法中手动创建的。
问题是为什么 MyObject
没有注入,可能有很多原因,其中之一是您没有在 MyObject
中定义 @Component
class 或者它不在您的组件扫描路径中,方法是在您的 Spring 应用程序 class 中添加 @ComponentScan(basePackages = "put-your-base-package-name")
。