I have the following scenario:
A bean Autowired in two classes, I populate the bean in one class, then I check the bean in the second class, it is not populated. Whereas, when I add a getter in the class where I populated the bean and call the getter, it returns the bean populated. Why can't I access that bean directly in the other class, shouldn't it be populated since it's acting as a singleton in spring context?
A JUnit4 test class loading the spring context from an xml file:
@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;
}
}
In the test class, myUtils.getMyObject().getId()
returns a correct id but the second line myObject.getId()
it returns null.
Why is MyObject which is set in MyUtils class and is @Autowired in both classes is not being updated when I access it directly in the test class.
When you're reassigning myObject = myDBObject;
in setMyObjectFromDB
method, you're creating a new object and saving it's referene in myObject
variable which is different from the one created with Autowired
.
When you use Autowired
, then it will assign the created bean's reference in the variable. But if you reassign that variable, it will point to the new object.
EDIT:
If you really need to update all the variables of myObject
with initialized with Autowired
, it is better to create a container class that stores myObject
variable.
public class MyObjectContainer {
@Autowired
MyObject myObject;
// Getters & Setters
}
In all the classes, where you're autowiring myObject
, use an object of MyObjectContainer
class instead. And when you want to update myObject
value, just update it in myObjectContainer
object with it's setter. So your MyUtils
would be like:
public class MyUtils {
@Autowired MyObjectContainer myObjectContainer;
public void setMyObjectFromDB() {
MyObject myDBObject = new MyObject();
//
// getting myObjectFromDB;
//
myObjectContainer.setMyObject(myDBObject);
}
public MyObjectContainer getMyObjectContainer() {
return myObjectContainer;
}
}