Is it common practice to communicate via field references. Let's say I have an instance injected all over my program. Since all classes are referencing the same instance I can simply change it's state, instead of informing all dependent classes via method calls? Isn't that a big advantage of dependency injection? Or do I turn a dependency injected variable turn into a global variable?
2 Answers
Variables don't get injected. Values get injected. When you inject a bean into another bean you are injecting that reference. References are values, see Is Java "pass-by-reference" or "pass-by-value"?.
You can have some spring bean in singleton scope that different parts of the application call, with some method which returns a value. For instance a spring boot application can have a Clock configured that various services or other components have injected into them, where they call the clock to get the current time.
If you do have a bean that contains some mutable value that gets set, be aware its scope will be limited to the application instance. If you have multiple instances of the application deployed. each one will have its own separate bean. Also changes aren't going to be guaranteed to be visible across threads unless you enforce that (with tools like locking, the volatile keyword, atomic variables, etc.).
Fundamentally OO is about message-passing, not about sharing memory. We want to limit global state because it's hard to reason about. Especially when you consider the high-concurrency of a web application and how quickly things can be changing, and how difficult it is to ensure changes are visible, in a lot of cases it's better to find alternatives to global variables.

- 94,330
- 19
- 181
- 276
-
So it seems you suggest message passing over memory sharing, mainly because we can keep the scope narrow and don't rely on invisible setups? For example, an object can never be sure that its state is (its members are) correctly set at the time it is requested. However, when the state is passed via a method call it's guaranteed to be processed correctly. For that we'd accept more boilerplate code and even tramp data from time to time? – MasterLu32 Dec 09 '19 at 22:49
-
@MasterLu32: maybe this is too broad to answer. but if you are using a variable then it seems like you are stuck with polling. and you may miss changes that happen when you're not checking. maybe that doesn't matter, i don't know what your use case is. but using messages seems a lot clearer. – Nathan Hughes Dec 10 '19 at 18:00
Assuming that the injected type is configured to use a Singleton, there shouldn't be any behavioral difference between using dependency injection and accessing a Singleton directly.
The advantages to using Dependency Injection generally center around how the code is written, and how it allows you to decouple the consuming classes from the specific requirement for that injected object to actually be a singleton.
For example, if you want to unit-test your consuming class, you probably want complete control over what the class perceives as the current state, and you probably don't want any effects of the code your testing to carry over into other unit tests: you don't want a test to pass when it is run all by itself but fail if it happens to run immediately after some other test.
Using Dependency Injection, your unit tests can encapsulate the entire interaction with the code being tested. The code that instantiates the class has complete control over what gets injected, so it doesn't have to provide a singleton value.
By separating the class that consumes an injected value from any specific knowledge about where that value comes from, or what its life cycle looks like, you're better able to maintain separation of concerns. If a future change requires a value to no longer be a singleton (e.g. maybe it needs to be dependent on the current user), you're in a better position to change how that injected value is provided without having to change code all over your code base.

- 151,543
- 27
- 246
- 315
-
I'm not sure if I understand you correctlly, but I aimed more at the question if DI injected beans should be used for communication over method passing. – MasterLu32 Dec 10 '19 at 00:28
-
The answer to that probably depends on what you mean by "communication". Injected beans are probably a good way to track the current state of your application. There are other tools, like an event bus, which might be more appropriate if classes need to respond to certain changes. – StriplingWarrior Dec 10 '19 at 22:02