Why does dependecy injection use public methods? Correct me if I'm wrong, but it's possible to change the implementation using reflexion.
5 Answers
DI is not a goal in itself. The purpose of DI is to enable loose coupling through favoring composition over inheritance, and that's only possible if you expose a public API for the purpose.
You can't recompose components in new and exiting ways without the public API.

- 225,310
- 48
- 427
- 736
That's a pretty blanket statement and isn't true. My preference is generally to use package-private constructors (or public constructors on package-private classes, since it doesn't matter then) for dependency injection since that allows you to instantiate and inject a class yourself (with no reflection or injector) for testing in a test class in the same package.

- 108,630
- 30
- 201
- 202
Keep in mind that the security policy may prevent one from calling protected, package private, or private methods even via the reflection API. If the DI framework is to work in all environments, then it can only rely on public methods.

- 10,675
- 1
- 45
- 50
Just to elaborate on the answer ColinD gave (I never even knew about package-private classes until a year of programming Java). With an app developed with a DI framework I believe you would make interfaces public and perhaps some abstract classes and Enums:
package org.my.service;
public interface Service {
public void process();
}
Then, the concrete implementation would be package-private (no public keyword)
package org.my.service;
class RealService {
public void process() {/*do something*/}
}
This enforces the concept of information hiding and means implementation details do not leak into the public API. It also means you cannot use the class outside of that package (compile-time error if you try -- you can't "new" it anywhere).
Again as ColinD said, you can unit test it because your unit test will reside in org.my.service.

- 31
- 1
DI frameworks have many ways to inject dependencies
- constructor injection
- setter injection
- initializer injection
- field injection
By using the first three, with modifier public
you can set the dependencies manually even if the class is used outside a DI framework.
However, the 4th option is widely used. The most common scenario where you may need to manually set the dependencies are unit tests. For that spring, for example, offers ReflectionTestUtils
, so that you can inject into fields with 1 line, and that is more or less fine.

- 588,226
- 146
- 1,060
- 1,140