4

I’ve been developing in Spring Boot for just over a year but have yet to understand the benefits of using an Autowired constructor and I was wondering if someone could explain this to me and what would be considered best practice.

Let’s say I have a bean as follows

@Component
public class MyBean {

    void doSomeStuff() {
    }

}

And I have a service that has a dependency on that bean

@Service
public class MyServiceImpl implements MyService {

    private MyBean myBean;

}

To me, the simplest way of injecting the dependency in this class would be to simply annotate the variable with @Autowired

@Service
public class MyServiceImpl implements MyService {

    @Autowired
    private MyBean myBean;

}

But there are other places online (and also other developers on my team) who favour something like this approach:

@Service
public class MyServiceImpl implements MyService {

    private MyBean myBean;

    @Autowired
    public MyServiceImpl(MyBean myBean) {
        this.myBean = myBean;
    }

}

To me, using a constructor like that is simply redundant code. Autowiring the bean is much simpler and straightforward than what appears to me to be boilerplate code.

  • To me, using a constructor like that is simply redundant code. Autowiring the bean is much simpler and straightforward than what appears to me to be boilerplate code. and are not you concerned about the magic of injecting a bean into a instace variable which is private and has no setter? Are not you worried about the huge technical debt this is generating on you, your coworkers? Are not you concerned about relaying too much on the Spring's magic paradigm instead of design good practices? – Laiv Jun 3 at 14:48
  • Are not you concerned about allowing others to create an instance of MyServiceImpl without the due dependency injection? – Laiv Jun 3 at 14:50
  • 2
    It's not that I'm not "concerned", it's that I wasn't aware how this was creating huge technical debt. If you could provide an example of why it's such bad practice, I'd appreciate it. – Space Cadet Jun 3 at 14:54
  • "Are not you concerned about relaying too much on the Spring's magic paradigm instead of design good practices?" Are there any resources on good design practices relevant to this discussion that you can recommend? I'd be interested in reading them. – Space Cadet Jun 3 at 14:55
  • 1
7

You use a real constructor for the same reasons that you use public getters and setters instead of making private variables public.

Some real-life examples: cell phones are not allowed in secure, information-sensitive physical locations. Any communication with that secure location must take place through a securely-established, controlled and encrypted communications protocol, not surreptitously by an unmonitored and uncontrolled rogue communications channel.

At a concert, you don't allow people to throw things over the fence to someone who's already in the stadium. Anything coming in or out must go through a gate.

If that's all there is to your code example, then it does appear like unnecessarily verbose boilerplate. But frequently we do other things in the constructor besides setting private variables, like validation. In many programming languages, changing the way you do this after the fact is a binary breaking change, so providing the constructor up front can be a sensible step.

Finally, the class should be able to function independently of the dependency injection. If you put an annotation on a private member, but fail to include a constructor, you've essentially tightly-bound that class to the DI container, and the class won't work without it.

  • "At a concert, you don't allow people to throw things over the fence to someone who's already in the stadium. Anything coming in or out must go through a gate." But I don't see how using a constructor makes the autowiring more secure? If there were no constructor requirements (like validation) then would it be of any benefit to use a constructor? – Space Cadet Jun 3 at 14:41
  • You make it possible to add validation later without breaking binary compatibility. – Robert Harvey Jun 3 at 14:43
  • 2
    Also, note that private members should really stay private. That's kinda the whole point of having private members. – Robert Harvey Jun 3 at 14:44
  • 2
    The whole point is allowing design good practices compatible with @Autowire. Having constructors is the MOST natural thing in OOP. The contrary, (what you call straightforward and simpler) is kinda scary. There are no real benefits on removing constructors, there's no simplicity at all on it. Constructors are among the most simple methods in OOP. Per se, they usually have very little complexity that worth implementing the magic of Spring IoC – Laiv Jun 3 at 14:54
  • 1
    For what it's worth, Java tends to be a very verbose language anyway. If you're looking to tame some of that verbosity, eliminating constructors is not likely to make much of a dent. – Robert Harvey Jun 3 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.