I've been scratching my head around developing a simple plugin based architecture on top of Spring, for one of my current apps. No matter how much separation one could achieve using patterns like MVC, one always reaches a point where coupling is inevitable.
Thus, I started weighing options. At first I thought that filters are a good one. Every plugin I'd make would be a filter, which then I will simply insert into the filter map. Of course, this will create a bit of overhead when enumerating and checking all the filters, but at least , controllers won't have to care what has happened to the data before it reached them, or what happens afterwards, they will just care to fetch the models (through DAO or whatnot) and return them.
The problem with this is that not all of my app requests are HTTP-based. Some are based on emails, others are internally scheduled (timed), so Filters won't help much, unless I try to adapt every type of incoming request to HTTPRequest, which would be too much.
Another one I thought about was annotation based AOP, where I annotate every method, where the plugin would intercept methods based on certain conventions. My problem with is that first I am not so experienced with AOP in general, and second, simply writing all those conventions already suggests a bit of coupling
By far the option that mostly appeals to my way of thinking is using Spring-based events. Every type of request handler within my app (web controller, email handler, etc) will be a sort of an event dispatcher, which will dispatch Spring events on every major action. On the other hand, plugins will simply listen for when a particular event happens, and do some logic. This will allow me to utilize point #1 as well, as some of those plugins could be filters as well, i.e when they receive a notification that a certain controller action is done, they may just decide to do nothing, and rather wait for when they get called by the filter chain. I see this as a somewhat nice approach. Of course here comes the overhead again, of dispatching events, plus the fact that every involved class will eb coupled with Spring forever, but I see this as a necessary evil.
My main concern regarding Spring events is performance, both in terms of latency, and memory footprint.
I am still not an expert, so a bunch of feedback here would be of tremendous help. Are spring events the best for this type of architecture, or there is another solution that I've missed? I am aware that there might even be some third-party solutions out there already, so I'd be glad if someone could point out one or two tried and proven ones.
Thanks.
The concept of a plugin can be achieved with the Spring bean factory. If you create a common interface you can define multiple beans that implement it and inject them where needed. Or you can use a factorybean to deliver the right plugin for the job.
Your idea of using events is called an 'Event Driven Architecture'. This goes a lot further than just plugins because it not only decouples from the implementation but also offers the possibility to decouple from which instance is used (multiple handlers), which location (multiple machines) and the time at which the request is handled (asynchronous handling). The tradeoff is an increased overall complexity, a reduced component-level complexity and the need for a messaging infrastructure. Often JMS is used, but if you just want a single-node setup both Spring and Mule offer simple in-memory modes as well.
To help you further you should expand a bit on the requirements you are trying to meet and the architectural improvements you want. So far you have mentioned that you want to use plugins and described some possible solutions, but you have not really described what you are trying to achieve.
Related
I am working on a web application (which happens to have a Java+Spring+postgres backend) and I am adding permission validation to my services to filter data access.
First, I was thinking about implementing my validations in Java and then annotate my services with something like org.springframework.security.access.prepost.PreAuthorize to have my validations invoked.
My main concert is about maintainability. As the project grows in size I have no guarantee that in the future all developers will remember or even care about permission enforcement when they add new features.
I turned to row level security but I have the following architectural problem:
Although RLS solves my maintainability problem, some of my services trigger asynchronous processes that write to the database but do not yield any session, which in turn yields the user permissions. This takes me back to preauthorisation and its maintainability problem.
Therefore I was wondering if there are other options besides these ones that I haven't considered yet?
Thank you for your time.
Hi i am using Spring 4 Async rest template to make 10k rest api calls to a web service. I have a method that creates the request object and a method that calls the web service. I am using Listenable Future classes and the two methods to create and call are enclosed in another method where the response is handled in future. Any useful links for such a task would be greatly helpful.
First, set up your testing environment.
Then benchmark what you have.
Then adjust your code and compare
(repeat as necessary).
Whatever you do, there is a cost associated with it. You need to be sure that your costs are measured and understood, every step of the way.
A simple Tomcat application might outperform a Spring application or be equivalent depending on what aspects of Spring's inversion of control are being leveraged. Using a Future might be fast or slow, depending on what it is being compared to. Using non-NIO might be faster or slower, depending on the implementation and the data being processed.
Are there any recommendations, best practices or good articles on providing integration hooks ?
Let's say I'm developing a web based ordering system. Eventually I'd like my client to be able to write some code, packaged it into a jar, dump it into the classpath, and it would change the way the software behaves.
For example, if an order comes in, the code
1. may send an email or sms
2. may write some additional data into the database
3. may change data in the database, or decide that the order should not be saved into the database (cancel the data save)
Point 3 is quite dangerous since it interferes too much with data integrity, but if we want integration to be that flexible, is it doable ?
Options so far
1. provide hooks for specific actions, e.g. if this and that occurs, call this method, client will write implementation for that method, this is too rigid though
2. mechanism similar to servlet filters, there is code before the actual action is executed and code after, not quite sure how this could be designed though
We're using Struts2 if that matters.
This integration must be able to detect a "state change", not just the "end state" after the core action executes.
For example if an order changes state from In Progress to Paid, then it will do something, but if it changes from Draft to Paid, it should not do anything.The core action in this case would be loading the order object from the database, changing the state to Paid, and saving it again (or doing an sql update).
Many options, including:
Workflow tool
AOP
Messaging
DB-layer hooks
The easiest (for me at the time) was a message-based approach. I did a sort-of ad-hoc thing using Struts 2 interceptors, but a cleaner approach would use Spring and/or JMS.
As long as the relevant information is contained in the message, it's pretty much completely open-ended. Having a system accessible via services/etc. means the messages can tap back in to the main app in ways you haven't anticipated.
If you want this to work without system restarts, another option would be to implement handlers in a dynamic language (e.g., Groovy). Functionality can be stored in a DB. Using a Spring factory makes this pretty fun and reduces some of the complexity of a message-based approach.
One issue with a synchronous approach, however, is if a handler deadlocks or takes a long time; it can impact that thread at the least, or the system as a whole under some circumstances.
I need to implement quite big system in Seam. I'm considering the way of designing the architecture. If it's good to use page controllers or application controllers or front controller or every each of them. If it's helpful to use backend bean or maybe there's no need to do that. If you have any suggestion or link to helpful article I will appreciate it.
Thanks a lot!
Daniel Mikucki
If you need to learn a lot about Seam for a project, I recommend you get the Seam In Action book, which is the best on the subject.
To answer your question, personally I prefer to use the pull-MVC style in Seam, where you refer to data in your view templates that Seam takes care of initialising, as needed, using #Factory methods. However, there is more than one way to do it in Seam, so it is worth reading about the alternatives first, hence the book recommendation.
Alternatively, build a few Seam applications first to throw away before you try to build one 'right' :)
Daniel,
It is good practice to use a front controller, most people aren't aware of that design pattern.
It is a really good design pattern to use because it ensures you are accessing the application through a single entry point. You can monitor everything that comes and goes easily with less configuration. You reduce the amount of possible code duplication because there is a single entry point. In addition to having less code to maintain, the code should be easier to follow since there is only one way in. You can then easily follow the execution flow of the application.
Unfortunately for Seam, there isn't really a front controller pattern. I haven't spent as much time as I would like to develop my own, but security and audit-ability are my number one focus.
As far as page / application controllers go, in Seam, you have more contexts or scopes available. Event, Page, Conversation, Session, Application, to name most of them.
If you're developing a controller or in Seam, a page action, most of the time, it will be event based. That is the shortest lived scope. If you have page flows, you would then use conversational-scoped components.
Take a look at the examples in the source code. You can do a lot with very little code, it is amazing, but at the same time, there is a lot going on that may take a while to pick up on.
The n-tier design that most places follow doesn't necessarily apply here. For most of my pages, I define a query that I'll use in XML (entity query), then I'll inject it into my page action and call it there. So instead of having a controller, service, dao, and entity classes, you end up with simply a page action, the queries, and entity classes. You can cut out the service and dao layers in most cases.
Your whole definition of a service might change too. For me, a service is a service provider such as notification, security (auditing), exception handling, etc. all of these services run in the background and are not tied to a particular http request.
Walter
Daniel,
I have used one controller per page, one service and one dao per entity.
Use case logic goes in the controller
Entity specific business logic goes in entity service.
Actions which span multiple entities you can create a facade service - something which sits between controller and entity services
While the above is a good and practical approach, ideally:
you could break out any non MVC code from controller into its own service class, ie. 1 service class per page
you should only access the entity dao via the entity service.
Here's how the control would flow:
Ideally:
UI
-> PageController.java
-> PageService.java
-> EntityService.java
-> EntityDao.java
Practically, you could trim down a few layers:
UI -> PageController.java -> EntityService.java
Or for actions touching multiple entities:
UI -> PageController.java -> Facade.java -> Entity1Service.java,Entity2Service.java
PageController.java would be a Seam #Component and in your ui you can refer it as:
#{pageController} and pull the data from the view.
In architecture, the most important thing is how you layer things in the stack is avoid circular dependencies between layers. For example, Entity Service should not reference Controller and so on.
The other important thing is to be consistent about layering in the entire application. Use code generators if you can to keep your code consistent across the application, it really pays off for large projects. Look into Clickframes if you are interested in code generation (Clickframes generates starter code for Seam apps with full JPA/valdiation/security support which you can then modify). See this Seam demo build with Clickframes if interested.
We have a project with a pretty considerable number of EJB 2 stateless session beans which were created quite a long time ago. These are not the first-line beans which are accessed from our client via RMI, rather they are used by that code to perform specific functions. However, I've come to believe that there's nothing to be gained by having them as session beans at all.
They do not need to be accessed via
RMI.
They do not retain any state,
they are just code that was factored
out of the first set of beans to
reduce their complexity.
They don't
have multiple different
implementations which we are swapping
out, each one has been as it was for
years (barring bug fixes and feature
additions).
None of them alter the
transaction that comes into them from the bean calling them
(that is they don't require a new
transaction, not participate in the
existing one, or otherwise change
things).
Why should these not all just be classes with a couple of static functions and no EJB trappings at all?
The only reason I can see is for clustering purposes (if you are doing clustering). That is the hand off to those beans could be on another VM on another machine if clustering is being done right to spread the load around.
That is likely not the case, and the movement to EJB's was just over-engineering. I'm suffering with that too.
Even transactions aren't really enough to justify it, you can have a single EJB that handles the transactions and call the different code through it via a Command type pattern.
There seems to be no reason why they shouldn't just be simple POJO's rather than stateless session beans. I think this is the conclusion that people came to after using EJB 1.x in this manner as well.
It's also the reason why frameworks such as Spring exist as an alternative to EJB's.
I'd say change them over to be just standard POJO's, but make sure you have a safety net of unit and functional tests (which might be a little bit harder with EJB's) to help you.