In Sling Models, you cannot use a non-public constructor to inject. Looking through the code, there doesn't seem to be any clear reason for this restriction. In my opinion, constructor injection should allow any constructor visibility.
Here are some discussion points:
- Private fields are allowed for use, so disallowing private constructors seems unnecessary.
- Private constructors may be bad practice (difficult to test), but Sling should not be telling users how to write their Java code. This is especially true for models, since it should work with POJOs, as stated in the documentation. It would be trivial to add checks to just allow default, protected, or public, but I feel that logic is unnecessary.
- Non-public methods could also be allowed, but that can be a separate ticket.
- A prerequisite of this would be to allow setter injection on models in the first place. Again, not the subject of this ticket.
- Threading concerns are minimal, but there could be possible deadlocks, as with any multi-threaded application that uses locks. In general, I think locking similar to how it is done in InjectableField would be sufficient. The risk of deadlock would be similar to the risk of the locking in injectableField.set(Object, Result<Object>).