Should I use AOP to address this cross-cutting concern? - java

I've used Spring AOP before, but I'm not sure if that's the best method to go about this problem.
There's a service-layer class that has autowired DAOs to save an object. When an object is successfully saved, a message should be sent (SMS) to the object's supplied phone number.
Is it standard practice to keep the service unaware of the of the messaging bean using AOP, or to inject the bean into the service and send the message?

It totally depends on Business requirement, you can achieve the same thing using Interceptors too. Once object is saved you can call the interceptor after save and can send the message through it, making the service unaware of message sending part.

I'm not totally sold on this being a valid use of AOP (see AOP use cases? )
Personally, I have no problem with the service layer being aware of the SMS message. However, as also mentioned in this thread, to avoid code duplication, I would look at an Entity Listener: http://www.mastertheboss.com/jboss-frameworks/hibernate-jpa/interceptors/jpa-entity-listeners

Related

How to use a custom ErrorMessageSendingRecoverer in Spring Cloud Stream

I'm using kafka binder if it matters.
I want to add some custom logic to the recover method of ErrorMessageSendingRecoverer (particularly - to modify a message a bit before publishing it to the error channel with adding new headers). Seems that extending from this class with overriding this method and register it as a bean would be a good idea.
However, I cannot imagine a way to do it while using Spring Cloud Stream. In the code of AbstractMessageChannelBinder it's neither injected as a bean nor allows you to use any customizers - it's simply created with new.
How to solve this problem? Maybe there is another (intended) way to do the same?

Strategies for exposing user identification from a REST endpoint back to the data-access/repository layer

The background: there is a requirement to attach auditing data to persisted entities, basically creation-timestamp + user ID and last-update-timestamp + user ID.
I'm not keen on passing the user ID as a method parameter through all layers/components. So I need to somehow pass user identifcation (derived from HTTP headers, the details are unimportant) through a REST endpoint (using RESTEasy, but that's probably not important, either) back to the data access/repository layer.
I've thought of using ThreadLocal but it feels a little hackish and might fail in a non-blocking IO environment. Maybe I'm wrong about that, not sure.
I also have a vague idea that AOP could help, though I'm not well-versed in AOP so not sure.
Any strategies appreciated, with or without code.
You can use entity lifecycle callback methods for your requirement: #PrePersist, #PostPersist, #PreUpdate, #PostUpdate.
It is one of the auditing strategies mentioned here.
It turns out that Spring's SecurityContextHolder is a reasonable place to do this (don't ask why the application isn't already integrating "properly" with Spring Security). It's basically the ThreadLocal option but with some nice interface around it.
The tradeoff is that you need to be acutely aware of the thread-bound nature of this solution. A controller that somehow uses other thread to do the work that needs the user context, will need to take some steps to make sure those threads can get it since they don't, by default, inherit the ThreadLocal. There is a mode you can set on SecurityContextHolder that will use inheritance of the ThreadLocal in any newly created threads, but that does not help if a thread pool is used (since threads won't be created by the request thread but rather pulled from the pool). Even then, most thread pools provide a way for the client thread to do "something" when obtaining and releasing threads, so it's possible to pass the security context on that way.

Why does Spring initialize the instances as singletons? What are some reasons that influenced their decision to handle initialization this way?

I don't understand the decision for why the Spring Framework is designed by default to return instances that are a singleton. So the same object is passed around when calling the application context. What are some reasons that influenced spring's decision to handle bean initialization this way? What are some bad things that can happen if all beans were initialized as prototypes?
Thank you in advance.
I think that Spring documents explain this point very well. Shortly the reason is that if your bean is stateless your do not need more than one instance. Since most beans are stateless "singleton" is a default scope. You can however change this. There are other scopes, e.g. session, request etc.
If for example you implement web store and need curt implementation session scope is what you need. If however you support special parameters that are sent for each request separately you probably want to use request scope for this purpose.
But beans that access database, perform authentication, send email or SMS, do other business logic can and should be implemented using singleton scope.

Executing code before and after #Transactional method

We have a Spring based application with a service layer which is annotated with #Transactional. We need to have code run before and after some transactional methods for the following reasons:
We need to synchronize access to the method based on a key. The thread needs to block before the start of the transaction.
We need to post a message on a queue if the transaction succeeds.
The options seem to be:
Create a class with similar methods to the service that can run the #Transactional method in a synchronized block and check for the return then post the message (would need a separate class due to AOP proxy problem). Services calling services, not nice, feels like a work-around.
Write an aspect to wrap around the #Transactional AOP which can do the synchronization and message posting. Might work but would rather avoid AOP.
Move the transaction down to the domain layer. Not desirable or possibly even feasible with the current implementation due to the way domain methods are reused in different workflows.
Code the transaction by hand in the service method and scrap #Transactional.
I would imagine this is a fairly common requirement. Probably I am missing an option 5, which is the obvious one!
I think I'd go with 2 unless you have some specific reasons to avoid AOP. Your problem is a classic example of where AOP can be used and it looks pretty good in the result. Here is a nice example of how to implement that (if you didn't read that already): Advising transactional operations
If AOP is really not an option, I'd go the 'Otherwise' option proposed by #Lawrence McAlpin.
Check out TransactionSynchronization callback interface. Spring can natively inform you what is happening with your transaction.
I would use a TransactionTemplate (your option 4) and programatically control the scope of the transaction in situations like this.
Otherwise, you could move the logic in your method out into a separate service, make that new service #Transactional, remove the #Transactional from the current method, and then surround the call to the new service with your pre- and post-transaction logic. I've taken this approach as well, but I prefer programmatic transaction management for requirements like this, as I think it's cleaner and, as you mentioned, services calling services (that are only ever needed by the first service) just feels like a hackish workaround.
if the key is being passed as part of the method call, then you can use java ReentrantLock to do the job.. its much simpler & cleaner.

Where to validate data in a web app (using Spring)

This is a follow-on to my question Spring Web MVC - validate individual request params.
I've figured out how to invoke the Spring Validator on domain objects that have been created from my inputs and how to have that validator honor the JSR-303 annotations on my classes themselves. The part I can't figure out is where in my code to perform this validation. The obvious approach is to do it in the controller and return a different model and view if there's a validation failure.
But I also have a service layer which sometimes gets calls to create/update objects from input sources other than the web controller. So it's tempting to implement validation there, but the only obvious way I can think of to report a failure is throw an exception. I see Spring provides BindException but the Javadoc also basically says not to use it in application code.
What is the common/recommended practice here?
I think the answer is both.
Controllers are associated with views. You don't want the validation to disappear if you change view technologies.
Services should assume that no one is safe and validate all incoming parameters.
Other answers are all good, I'll just state one important rule:
Each subsystem/layer should validate its input, no matter where it comes from.
When you encapsule the validation logic inside of a ValidationService you can use it inside your controllers and services. As you want the user to interact with the input and to correct invalid information you should be able to display validation problems in your web view.
Sometimes you might have data (CommandObjects, Forms) which is not directly visible in the service layer and then the validation should be done in the controller which then passes the information into the service layer.
When you design your application you should think about the interaction between each layer. Mixinig validation logic into every layer might not be needed. Think about how data gets into your system. If controllers are your main entry point you can perfectly place it there since no data gets into your services without passing the validation.
At least you should validate inputs at the service layer, in order to guarantee correctness. Additionally you can do validations further up to get better usability, etc. if needed.

Categories

Resources