Autowired Bean in two classes not being updated after accessing it from the second class

老子叫甜甜 提交于 2019-12-13 08:34:41

问题


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.


回答1:


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;
    }
}



回答2:


Looking at the code, the MyObject is not injected in either of the two classes. You got the impression that it was injected in the MyUtils class because you actually created it manually in the setter method.

The brings the question to why MyObject is not injected, and there could be many reasons for that one of which is that you do not have @Component defined in the MyObject class or it is not in your component scan path by adding @ComponentScan(basePackages = "put-your-base-package-name") in your Spring application class.



来源:https://stackoverflow.com/questions/53830819/autowired-bean-in-two-classes-not-being-updated-after-accessing-it-from-the-seco

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!