Question

I was thinking about some of my services. Some of them looks like this:

@Service
public class UserService {

   @Autowired
   UserDao dao;

   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ....



}

I was thinking.. if this concept of autowiring other services into a single service is pretty common, why not creating a "Master-service" :

@Service
public class MasterService {


   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ...
   @Autowired 
   LastService servN;


}

and autowiring this service in to all services.

@Service
public class AnyService {

   @Autowired 
   MasterService masterSevice;
}

this way we wont have many services per service, but only a single one to rule them all..

Two questions rises:

1) Since masterService contain all services we have a loop in injection. can we solve it?

2) if the answer to question 1 is "yes" - is this "masterService" a good practice?

Was it helpful?

Solution

1) Spring is able to handle dependency loops in many cases, especially when not using constructor injections.

2) Despite this. You should absolutely avoid this design. It breaks many principles of good architecture:

  • Components should only have access to as few other components as needed. Demeter's Law
  • Separation of concerns. A service should not at the same time handle business logic, and presentation.
  • Abstraction levels. A service should not handle both a logical view of data, and a persistence view of it.

Breaking such principles may lead to bad situations such as:

  • Inability to follow code paths (a single request will go through 12 services in an order that is hard to understand and relies on many levels of conditional logic).
  • Difficulty to know which components rely on each-other.
  • Strongly coupled code (changing a low level service will lead to changes in high level services).

The advantages you gain from such a design are very small (you just avoid a few @Autowired annotations) and are not worth the risk.

OTHER TIPS

  1. Why would have a circular dependency? There is one service that contains all the other services, and no other service that contains it. Having said that, a circular dependency could be easily solved by setting the dependency as property and not as constructor arg.

  2. I don't think so, it is nice pattern to declare kind of hierarchy (in endpoints for instance), but what are the pros of it in this way? You can Autowire every service that you want also without it.

1) MasterService doesn't necessarily contain a loop. If it does, then you'll run into problems, and it's much simpler not to construct your beans in a loop in the first place.

2) It's possible for this to be effective if you're injecting into lots of short-lived beans, but this approach has the downside that anyone who meddles with the MasterService instance can screw up the services for the other beans. You can hide this behind getter methods, but lumping everything together usually doesn't provide much benefit.

Instead, it's usually best to group related services together, maybe OtherService1 and OtherService2, and to place them on an interface. This makes mocking for testing much easier and keeps related concepts together (ideally in their own jars/modules).

I haven't come across such pattern before (one service containing other services). What I commonly seen and used is something like below -

*SpecificController1 --> SpecificService1 --> SpecificDao1

SpecificController2 --> SpecificService2 --> SpecificDao2

Now, if SpecificService1 needs some functionality already available in SpecificService2, only then it will refer to SpecificService2.

So, I have few questions about the pattern described above:

  1. How the MasterService would be used? i.e. any controller (or anyone) requiring any service would first use MasterService to get a reference to the actual service or MasterService would act as a delegate?
  2. In what scenario, do you need such design and what are the advantages?
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top