I've registered my custom class as serviceCollection.AddScoped<IMyClass, MyClass>() to inject it to my Consumer constructor. How can I access message Headers in MyClass constructor on every request?
Thanks!
You can add a ConsumeContext dependency on MyClass, which will be resolved within the scope of the consumer.
Related
I injected ConsumeContext into MyClass constructor. MyClass is registered as Scoped and injected into MyCommandConsumer constructor. When consumer receives a message in the Consume method ConsumeContext contains Message. But ConsumeContext injected in MyClass constructor (or even in MyCommandConsumer constructor) doesn't. All of the non-public properties return ConsumeContext Not Available exception (or something like this).
What am I doing wrong?
It's because the context of consuming a message is scoped to one message. Even though the consumer is instantiated per message if it implements IConsumer<T>, only the Consume message gets the current message context. That's what the Consume method is for.
The ConsumeContext<T> is not a dependency, it is a context, therefore it should not be injected, because dependency injection is, as the name suggests, for injecting dependencies and not for passing parameters. The ConsumeContext<T> is a parameter, not a dependency.
If your consumer's dependency needs to publish a message, it should put IPublishEndpoint on its constructor.
If your consumer's dependency needs to send a message, it should put ISendEndpointProvider on its constructor.
As stated in the other answer, depending upon ConsumeContext is not recommended.
I am trying to understand how ControllerAdvice is working in SpringBoot. It is suggested that for per application there should be one ControllerAdvice. But my question is how this ControllerAdvice is tied to Controllers and catching the exceptions. So basically what is the underhood?
Spring AOP works with proxies.
That is when you annotate a class with any of AOP annotation spring will create a proxy class by extending your annotated class and all the methods will be overridden there in the proxy class.
Thus here after when you call a method in your class spring will call the proxy object method first then your actual method. This is Spring AOP knows whether the method has been called or thrown some exception or returned successfully etc etc.
This is the reason why when you call a private method with in the class AOP cannot intercept that method call.
I have a service class which is annotated with #Validated.
In this class I have a method with an argument which is annotated with #Valid.
If the method is called from another class instance with an argument that is not valid an exception is thrown.
As expected an error of type ConstraintViolationException is thrown.
If I call this method from another service method (internal call) no validation is performed and an error arises in the body of the method.
This is not what I want. Apparently calls made from within are not validated.
Investigating the problem I found out that the method was not invoked using a Spring proxy bean.
I fixed the problem by retrieving the proxy from the (#Autowired) application context and invoke the method using the proxy:
((T) context.getBean(this.getClass()).myMethod(validatedArgument)
This is an ugly solution.
How can I configure Spring so that method calls made from within are validated?
There is a tricky way to autowire the service to itself.
#Service
public class MyService {
#Autowired
private MyService copy;
private void call() {
//myMethod(validatedArgument);
copy.myMethod(validatedArgument);
}
}
The way Spring handles aspects is such that they are only invoked when one instance sends a message to a different instance. There are some ways to overcome this, but in your case, the fact that you want to do it is probably revealing a design flaw.
I have written a camel component by extending DefaultComponent and also have the associative classes implemetation for endpoint, consumer, producer. My producer is extending the camel DefaultProducer and I want to inject a spring bean inside this class, so that whenever a route will be executed like
<route id="myRoute"><from uri="file://inbox"/><to uri="myComp://outbox"/>
I will be able to get the file from the file system and store it into database. For storing the file into the DB I have a service class instantiated by the spring container, but whenever I inject that bean into MyProducer we are getting null.
I recongnized the problem was not about Camel, it is related to the spring and I was injecting the bean in a wrong way. I resolved the problem by implementing the ApplicationContextAware interface into my helper class and storing the spring context as static variable and with the help of this helper class I am able to get spring bean inside MyProducer class. Thanks for spring ApplicationContextAware interface.
Is it possible to set a session attribute in a manager class (class which is not a controller and is marked as #component)?
The scenario is like this, from my Controller i'm calling a manager class which does some logic. I want to store the result of this logic in the session, so that i can use it in the later requests.
No. #SessionAttribute is a controller-specific concept. To get similar behaviour in other components you can use session-scoped beans.