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?
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.
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.
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:
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?
In what scenario, do you need such design and what are the advantages?
Related
I have been searching for long time in the Internet, if Spring supports the "cache tag pattern" but seems it doesn't.... How do you implement this cache pattern in Spring???
An example of this cache pattern can be seen in Drupal cache tag implementation, I will create an example of how would that look
#Service
#AllArgsConstructor
class TicketService {
private final UserRepository userRepository;
private final ProductRepository productRepository;
private final TicketRepository ticketRepository;
#Cacheable(cacheNames = "global-tags-cache", tags = { "ticket:list", "user:#{user.id}", "product:#{product.id}"})
public List<TicketDto> findTicketsForUserThatIncludesProduct(User user, Product product) {
var tickets = ticketRepository.findByUserAndProduct(user, product);
}
#CacheEvict(cacheNames = "global-tags-cache", tags = "ticket:list")
public Ticket saveNewTicket(TicketRequestDto ticketRequestDto) { ... }
}
#Service
#AllArgsConstructor
class ProductService {
private final ProductRepository productRepository;
#CacheEvict(cacheNames = "global-tags-cache", tags = "product:#{productRequestDto.id}")
public Product updateProductInformation(ProductRequestDto productRequestDto() {
...
}
}
#Service
class NonTagCacheService() {
#Cacheable(cacheNames = "some-non-global-cache-store")
public Object doStrongComputation() { ... }
}
The idea is to handle the responsability of the "tag eviction" where it belongs to, for example TicketService wants its cache to be break when user is altered, or when any ticket is altered, or when the specified product is altered... TicketService doesn't need to know when or where Product is going to clear its tag
This pattern is strongly useful in Drupal, and makes its cache very powerfull, this is just an example, but one can implement its own tags for whatever reason he wants, for example a "kafka-process:custom-id"
As M. Deinum explained, Spring's Cache Abstraction is just that, an "abstraction", or rather an SPI enabling different caching providers to be plugged into the framework in order to offer caching capabilities to managed application services (beans) where needed, not unlike Security, or other cross-cutting concerns.
Spring's Cache Abstraction only declares fundamental, but essential caching functions that are common across most caching providers. In effect, Spring's Cache Abstraction implements the lowest common denominator of caching capabilities (e.g. put and get). You can think of java.util.Map as the most basic, fundamental cache implementation possible, and is indeed one of the many supported caching providers offered out of the box (see here and here).
This means advanced caching functions, such as expiration, eviction, compression, serialization, general memory management and configuration, and so on, are left to individual providers since these type of capabilities vary greatly from one cache implementation (provider) to another, as does the configuration of these features. This would be no different in Drupal's case. The framework documentation is definitive on this matter.
Still, not all is lost, but it usually requires a bit of work on the users part.
Being that the Cache and CacheManager interfaces are the primary interfaces (SPI) of the Spring Cache Abstraction, it is easy to extend or customize the framework.
First, and again, as M. Deinum points out, you have the option of custom key generation. But, this offers no relief with respect to (custom) eviction policies based on the key(s) (or tags applied to cache entries).
Next, you do have the option to get access to the low-level, "native" cache implementation of the provider using the API, Cache.getNativeCache(). Of course, then you must forgo the use of Spring Cache Annotations, or alternatively, the JCAche API Annotations, supported by Spring, which isn't as convenient, particularly if you want to enable/disable caching conditionally.
Finally, I tested a hypothesis to a question posted in SO not long ago regarding a similar problem... using Regular Expressions (REGEX) to evict entries in a cache where the keys matched the REGEX. I never provided an answer to this question, but I did come up with a "generic" solution, implemented with 3 different caching providers: Redis, Apache Geode, and using the simple ConcurrentMap implementation.
This involved a significant amount of supporting infrastructure classes, beginning here and declared here. Of course, my goal was to implement support for multiple caching providers via "decoration". Your implementation need not be so complicated, or rather sophisticated, ;-)
Part of my future work on the Spring team will involve gathering use cases like yours and providing (pluggable) extensions to the core Spring Framework Cache Abstraction that may eventually find its way back into the core framework, or perhaps exist as separate pluggable modules based on application use case and requirements that our many users have expressed over the years.
At any rate, I hope this offers you some inspiration on how to possibly and more elegantly handle your use case.
Always keep in mind the Spring Framework is an exceptional example of the Open/Closed principle; it offers many extension points, and when combined with the right design pattern (e.g. Decorator, not unlike AOP itself), it can be quite powerful.
Good luck!
In a typical CRUD application we could have entities such as users, orders, invoices etc.
For the service layer it's a common pattern to create the service interface and its implementation.
UserService
UserServiceImpl
OrderService
OrderServiceImpl
InvoiceService
InvoiceServiceImpl
I know it's a good practice to code in terms of interfaces, but for this particular case where the service implementation most probably won't change, do we really have to create an interface and its implementation with that ugly "Impl" suffix?
It might be that I just have a problem with that naming convention? Is there another way to address the design and creation of the service layer?
This might be a slightly different approach in the naming convention:
UserService
DefaultUserService
OrderService
DefaultOrderService
InvoiceService
DefaultInvoiceService
However, I feel that we are still coding in terms of interfaces "just" for the sake of coding in terms of interfaces in a situation where the implementations most probably won't change.
I have a spring MVC application. Each controller of the application auto-wires the #Service components it needs to interact with. A Sonarqube analysis has detected that there was some duplication in this: some controllers may use the same services, in which case the #Autowired annotation and the corresponding fields are indeed the same.
For instance, the following would be duplicated in many controllers:
#Autowired
private FooService fooService;
#Autowired
private BarService barService;
This is a minor issue, and I don't know whether/how I should address this. Since all my controllers inherit an AbstractController, and all services are singletons, would it make sense to put all #Autowired elements in the base class, in protected fields?
If the dependencies already are in the subclasses, you probably have a reason for that, e.g. they do not conceptually belong in the abstract class. Keep them in the subclass if so.
It's important to adhere to the DRY principle, but don't be fanatic about it. Duplicating code gives you flexibility, and class dependencies are a typical place where you want such flexibility. Not to mention that the code is simpler with such duplication.
Static code analysis is good for providing pointers to improve your code, but they shouldn't be followed blindly.
I'm new to using Spring with Neo4j and I have a question about #Autowire for a GraphRepository.
Most examples I've seen use one #Autowire per Controller, but I have two Nodes I need to modify at the same time when a particular method is called in the controller. Should I simply #Autowire the repositories for both nodes (eg per the code below)? Is there any impact if I do this in a second controller with the same repositories as well (so if I had a ChatSessionController which also #Autowired ChatMessageService and ChatSessionService)?
ChatMessageController.java
#Controller
public class ChatMessageController {
#Autowired
private ChatMessageService chatMessageService;
#Autowired
private ChatSessionService chatSessionService;
#RequestMapping(value = "/message/add/{chatSessionId}", method = RequestMethod.POST)
#ResponseBody
#Transactional
public void addMessage(#RequestBody ChatMessagePack chatMessagePack,
#PathVariable("chatSessionId") Long chatSessionId) {
ChatMessage chatMessage = new ChatMessage(chatMessagePack);
chatMessageService.save(chatMessage);
// TODO: Make some modifications to the ChatSession as well
}
}
Any help would be much appreciated! I've been googling and looking through Stackoverflow to understand this better but I haven't found anything yet. Any pointers in the right directions would be great.
Another underlying question is, should I be (and can I?) modifying other Nodes in a GraphRepository that handles a particular node? Eg Should my GraphRepository be able to modify my GraphRespository?
Thanks!
I'm not convinced that this is a SO question, it's not really a Neo4J or Spring question either, it is more about the architecture of your application. However assuming that you understand the negatives of class fan out, and how to use the #Transactional annotation to achieve what you want then the answer to your question is that it is just fine to have many Repositories (Neo4J or otherwise, autowired or otherwise) in your class and in as many classes as you want.
Neo4J transactions default to Isolation level READ_COMMITTED and if you need anything else, you need to add the guards/locks yourself. Nested transactions are consideredd tobe the same transaction. The Spring #Transactional annotation relies on proxies that you should be aware of as they have implications when calling methods from within the same class.
I would go through this tuotorial over at Spring Data and get your head around how real world vs domain vs node models differ, there will be cases where one repository impacts another node type but I would think it is often transparent to you (i.e adding relationships). You can do what you like in each repository (the generic nature of them is largely confined to all of the built in CRUD and queries derived from finder-method names (see documentation ) using the #Query annotation, and some queries have side effects, but largely you should avoid it.
As you start adding multiple repositories to multiple controllers I think that your code will begin to smell bad and that you should consider encapsulating this business logic off on its own somewhere, neatly unit tested. I also wouldn't tie myself to one controller per data object, it would be fine to have a single ChatController with a POST/chat/ to create a new session and POST /chat/{sessionId} to add a message. Intersting questions on Programmers:
How accurate is "Business logic should be in a service, not in a model?"
Best Practices for MVC Architecture
MVC Architecture — How many Controllers do I need?
What is the difference using #Autowired annotation and new key ?
Let's within a class what would be the difference between :
#Autowired private UserDao userdao;
and
private UserDao userDao = new UserDaoImpl();
Is there an impact on the performance?
Besides low coupling, that others have already touched on, a major difference is that with the new approach, you get a new object every time, whether you want to or not. Even if UserDaoImpl is reusable, stateless and threadsafe (which DAO classes should strive to be) you will still create new instances of them at every place they are needed.
This may not be a huge issue at first, but consider as the object graph grows - the UserDaoImpl perhaps needs a Hibernate session, which needs a DataSource, which needs a JDBC connection - it quickly becomes a lot of objects that has to be created and initialized over and over again. When you rely on new in your code, you are also spreading out initialization logic over a whole bunch of places. Like in this example, you need to have code in your UserDaoImpl to open a JDBC connection with the proper parameters, but all other DAO classes have to do the same thing.
And here is where Inversion-of-Control (IoC) comes in. It aims to address just these things, by decoupling object creation and life-cycle from object binding and usage. The most basic application of IoC is a simple Factory class. A more sophisticated approach is Dependency Injection, such as Spring.
Is there an impact on the performance?
Yes, but it's most likely not going to be very significant. Using Springs dependency injection costs a little more in startup-time as the container has to be initialized and all managed objects set up. However, since you won't be creating new instances of your managed objects (assuming that is how you design them), you'll gain some runtime performance from less GC load and less object creation.
Your big gain however is going to be in maintainability and robustness of your application.
The above comments are correct, but here I am going add some example that helps to you.
Look We have 100 Classes that uses UserDao class, And you get dao instance like that:
private UserDao userDao = new UserDaoImpl(); in 100 places,
After few weeks the requirement changed and we need to use LdapUserDao or something similar
class LdapUserDao implements UserDao{
}
that implements UserDao. What do you do? How do you handle your new keywords, You tied impl class into usage.
If you use #Autowired in 100 places then from one place (if you use xml based config then, just go xml and switch to another UserDao from xml, if annotation the go to that component and switch Spring annotation to proper one) manage it, so in 100 places it appears. This is what is called DI pattern. This is whole purpose of DI
Another important thing is with spring annotation even you can manage object scope, but with new keyword no way(unles you do dumb singleton or something like that),
I am sure with new keyword you can no have
Prototype
Request
Single
Scoped objects
In terms of performance, It is quite difficult to say, unless to see your code. But I am sure at worst case they may have equal performance, otherwise springs way is fast, because As I know dao class should be singleton, not prototype, so whole project you will have on userdao object in spring way, with new way It depends where you are loosing reference to dao object. But Leave the performance. Do not consider performance over good design. All time 1st make it in good manner(not fast manner) with good design, then look it's performance.
You will get NullPointerException if you use
private UserDao userDao = new UserDaoImpl();
because it doesn't set the session reference that was declared in the *context.xml.
At runtime, you'll get a UserDaoImpl instance asigned in the userdao attribute in both cases.
But the first approach implies the ussage of the Dependency Injection pattern, that has some advantages over the second approach:
Your class now depends on an Interface, so it can work with any implementation of UserDao (maybe one that uses and RDBMS, other that uses XML files as a repository)
As you depend on an Interface now, Unit Testing and Mocking are pretty easy and straightforward.
Low-coupling is nice attribute to have in your code.
So you should prefer the second approach over the first, specially if your already using Spring (that's the idea behind an Inversion-Of-Control container)