2

Let's say I have a Spring Boot class:

public class SomeClass {

    private ApplicationContext applicationContext;
    private MessagingService messagingService;
    private ClientReportFactoryImpl clientReportFactory;
    private TerminalReportFactoryImpl terminalReportFactory;
    private XMLView xmlView;
    private PrepareXMLService prepareXMLService;

And I have a constructor in that class:

@Autowired
    public SomeClass (ApplicationContext applicationContext, MessagingService messagingService, ClientReportFactoryImpl clientReportFactory,
                                                                TerminalReportFactoryImpl terminalReportFactory,
                                                                XMLView xmlView,
                                                                PrepareXMLService prepareXMLService) {
        Assert.notNull(applicationContext, "ApplicationContext must not be null!");
        this.applicationContext = applicationContext;
        Assert.notNull(messagingService, "MessagingService must no be null!");
        this.messagingService = messagingService;
        Assert.notNull(clientReportFactory, "ClientReportFactory must not be null!");
        this.clientReportFactory = clientReportFactory;
        Assert.notNull(terminalReportFactory, "TerminalReportFactory must not be null!");
        this.terminalReportFactory = terminalReportFactory;
        Assert.notNull(xmlView, "XMLView must not be null!");
        this.xmlView = xmlView;
        Assert.notNull("PrepareXMLService must not be null");
        this.prepareXMLService = prepareXMLService;
    }

Is it considered bad practice to use that many dependencies in a class constructor? Should I refactor my classes so that there are only 1-2 DI's in a constructor?

Deniss M.
  • 3,617
  • 17
  • 52
  • 100
  • It really depends on your overall application structure. But it is generally considered a bad practice to have too many dependencies. It is a good idea to often think about why are all these services required in a single class. Single Responsibility Principle - Not necessary to follow it strictly, but good to think about often – kjsebastian Oct 25 '16 at 08:26
  • This is the reason I want to make changes. I think it is a bad design to have so many DI's in a single class. I need to refactor and see if I can remove some of the responsibilities of this class and delegate them somewhere else. – Deniss M. Oct 25 '16 at 08:32
  • Why do you even need all those dependencies in your `Application` class. That should, generally, be only for configuration/bootstrap and shouldn't contain logic. Looks like you are injecting them to be used in other `@Bean` methods. – M. Deinum Oct 25 '16 at 09:51
  • That is correct, but I think the latest version of Spring doesn't require that any more. I could be wrong though. – Deniss M. Oct 25 '16 at 10:35

2 Answers2

1

You shouldn't invoke all of your services right in Application class, there is a nice guide on how to structure your code (this and the following chapters) so it could look like this:

com
+- example
 +- myproject
     +- Application.java
     |
     +- domain
     |   +- Customer.java
     |   +- CustomerRepository.java
     |
     +- service
     |   +- CustomerService.java
     |
     +- web
         +- CustomerController.java

Basically the idea is, that your Services are being annotated with attributes like @Service (obviously), so that they would be picked up by @ComponentScan in your Application.

gtonic
  • 2,295
  • 1
  • 24
  • 32
  • 1
    I am asking about the amount of DI in general per class. Application class was a bad example here. My bad. – Deniss M. Oct 25 '16 at 10:36
  • I see. So the only thing I could tell - from my personal experience there are not more that 3 injections per class, otherwise I would start thinking about how to externalize these dependencies. – gtonic Oct 25 '16 at 10:53
  • I heard about the requirement of 5. But then again, what about the situation when I have to run a Service which could use multiple tables to collect data. Then in theory I could use quite a lot of repositories due to the complexity of the queues. – Deniss M. Oct 25 '16 at 10:56
  • 1
    If you can influence the design of the repositories also, you might consider thinking of aggregate roots here (http://stackoverflow.com/questions/1958621/whats-an-aggregate-root), where you might end up with a fewer amount of repositories. At least I figured out, that most of the time I didn't need a repository for each single entity... But don't know if this might help in your case. – gtonic Oct 25 '16 at 11:49
  • Thanks, I'll look into that. – Deniss M. Oct 25 '16 at 11:51
  • 1
    maybe you've to consider the microservice architecture and distribute the concerne per micro-service. also you've to be aware of too many injections as it could be/become a SPOF. Testability will be hard as you'll have to mock as many services as you inject what will make even the test code unreadable. – Abderrazak BOUADMA Oct 25 '16 at 12:47
1

depending on your application if you need dependancies defined there is a cleaner way to reduce constructor code by using Lombok annotation: @RequiredArgsConstructor(onConstructor_ = {@Inject})

This will auto Inject all the dependancies defined as private final Dependency1 dep1;

Meghana Randad
  • 430
  • 5
  • 13