I am working on Spring Reactor to write REST Services. I was wondering if there is an annotation to Reactor.receive method like we have #Selector and #ReplyTo
Such that :
in.consume(req -> reactor.sendAndReceive("test.httprequests", Event.wrap(req.getUri()), (Event<String>ev) -> {
invokes the annotated method.
You should be able to just return a value from the method you annotate with #Selector to handle test.httprequests events. The wiring bean should treat that method the same as a receive, which is actually just an alias for being aware of the replyTo.
Related
I am developing a Spring Boot application using reactive programming. I need to apply Spring Expression Language Related logics inside that application. I will mostly use expression parser related approach as mention in this link.
Since my application is reactive, is it ok to put SpEl related code inside a map like below,
return Mono.just(Person("name", "age:12"))
.map { person ->
// SpEl expression parser related logics here
});
or do I need to execute SpEl related logics in a separate thread using an approach like this
Mono blockingWrapper = Mono.fromCallable(() -> {
return /* SpEl expression parser related logics here */
});
blockingWrapper = blockingWrapper.subscribeOn(Schedulers.boundedElastic());
It is okay to put to the code for actual parsing in the code in map, however suggest to instantiate the Evaluation Context in the Bean which is calling it and pass it using Closure concepts of lambda method.
This is because SpEL does optimization which will be lost if it gets instantiated every time.
Does #Beforemethod() and beforeInvocation() listener do the same? Please help with the difference!
#Beforemethod: The annotated method will be run before each test method meaning Methods annotated with #Test annotation
If you have implemented the IInvokedMethodListener listener
void beforeInvocation(IInvokedMethod method, ITestResult testResult)
void afterInvocation(IInvokedMethod method,ITestResult testResult)
then IInvokedMethodListener will be invoked for configuration(#BeforeSuite...) and test methods (#Test ...).
From an execution stage perspective, both get executed before a method annotated with #Test is called. It allows you to do any kind of setup you need for a test.
But when do you use what will be based on what is it you want to do.
If you have a specific setup for only a few tests, I will use #BeforeMethod in a class which would apply only to a few tests.
But if it is an suite wide setup, say initializing a driver object or creating an API token which needs to be done for every single test in your suite, then I would prefer listeners.
I have this kind of situation, where i have a multimap which i add in the end to Oracle DB, which converts empty string("") to null, is there a way i can guarantee in the code that multimap will not allow adding an empty key? (for example Multimap.put("", "some value"))
Thanks.
Both the keys and values of Guava's MultiMap are #Nullable and it doesn't have out of the box functionality to add a validation. So I would just build a validation in the code that puts the values. Something like:
if (!key.isEmpty){
multiMap.put(key, value);
} else {
log("Could not add " +value) // or throw an exception or do something else
}
Updated: after OP clarified that above doesn't apply to his use case, because parsing is done through Spring.
You could look into using ForwardingMultiMap:
A multimap which forwards all its method calls to another multimap. Subclasses should override one or more methods to modify the behavior of the backing multimap as desired per the decorator pattern.
default method warning: This class does not forward calls to default methods. Instead, it inherits their default implementations. When those implementations invoke methods, they invoke methods on the ForwardingMultimap.
https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ForwardingMultimap.html
I have never used this class myself, but it sounds like you can use it to forward to a subclass of your own design. Then in that subclass you could build the validation into the put method.
I have a method in an #Aspect service method called logChangesAndAnnounceNewContributions that fires whenever somewhere in the webapp the save method of Spring-data's JpaRepository is called. I don't want the logChanges method to be called when the save method is used within the Aspect class itself, so i used this in the pointcut definition !within(Services.SystemListenerService). But its not having any effect! The save method is still being called despite using this condition in the definition. The full definition looks like this:
#AfterReturning("execution(* org.springframework.data.jpa.repository.JpaRepository.save(..))" +
"&& !within(Services.SystemListenerService) && args(entity)")
private void logChangesAndAnnounceNewContributions(Object entity){
What am i missing here?
EDIT: I tried changing !within content to !within(#org.aspectj.lang.annotation.Aspect *) but that doesn't work either..
Assuming that Services.SystemListenerService is the fully qualified name of your aspect (class name SystemListenerService, package name Services with strange upper-case first letter), within() does not work because at the time of execution(* org.springframework.data.jpa.repository.JpaRepository.save(..)) we are not within(Services.SystemListenerService) anyway but rather within(org.springframework.data.jpa.repository.JpaRepository). So there is the logical error in your pointcut.
There are ways to solve this in AspectJ, such as
call(A) && !adviceexecution(),
execution(A) && !cflow(execution(B)),
but both pointcut types are unsupported in Spring AOP. So you
either need to activate full AspectJ via LTW in Spring
or abuse some Spring methods in order to get the real object underneath the proxy via ((Advised) myProxy).getTargetSource().getTarget() and call the method directly on that object from your aspect
or obtain a stack trace from a newly created exception or from the current thread and inspect it manually - very ugly.
Sorry, but Spring AOP is just "AOP lite", I think you should go for AspectJ. The second option is also a bit hacky but will probably work.
I have a JAX-RS web service that was generated by Netbeans. There are non-abstract facade classes for the service's endpoints. The persistence context is being injected into the non-abstract facade. Everything is working well and I see my data being returned to Fiddler.
We are using DTOs and I am implementing an assembler pattern. So, in the non-abstract facade's constructor, I am creating an instance of the assembler, and am passing the facade's entity manager instance into it. Unfortunately, it seems that the injection of the persistence context has not happened before the facade's constructor has been called, so I cannot pass the entity manager instance into the assembler for its to use in mapping operations. Kind of a chicken-before-the-end situation... I cannot figure out how to make this work... Is there some kind of post-constructor method that I can override and perform the initialization of the assembler and pass in the entity manager to it? I'd really appreciate your help and suggestions.
Thank you for your time and ideas,
Mike
Use method marked with #PostConstruct annotation. Like this:
#PostConstruct
private void init() {
// I'm called after all injections have been resolved
// initialize some object variables here
...
}
In that method you can use both, object fields initialized in the constructor and passed by injection.