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.
Related
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.
Spring is auto-wiring in a request parameter - let's call it "bob".
I don't know where nor how it is doing this, so I cannot debug it. What spring specific code (using intellij, so I can at lest set a conditional) would be appropriate to find where the auto-wiring of the request parameter is happening, so I can work out what the system is doing?
I think I understood the question, so I will try to answer it as best as I can.
You are facing a dilemma of choosing between managing your instances, or letting Spring manage them. If you let Spring manage dependency injection, you will often face situations where you wish you had more fine control over the beans lifecycle.
By default, Spring beans are "singletons", which means that only one
instance of that object will be created, and every class that demands
a dependency injection of that object will receive the same instance.
The first step on beans lifecycle is its construction. You can setup a breakpoint to catch that moment on any method annotated with #PostConstruct. This article describes the need of running some code on bean initialization, and how it is solved by this annotation. For example:
public class AnyBean {
#PostConstruct
public void init(){
// any code or breakpoints inserted here will
// be run whenever an instance of this bean is created.
// if a singleton bean, only one instance is created and,
// only one #PostConstruct will be called.
// If a bean is a prototype bean, a new instance will be created
// for every dependency injection, and hence one #PostConstruct
// will be called for each.
}
}
I have a CDI producer method which creates an UserBean. The producer fires an UserBeanEvent. Other beans rely on that user bean and those beans may be used in the observer methods.
CDI again tries to create the user bean, the producer is invoked, the event is fired and so on - endless loop.
Is there any neat way to fire the event AFTER the producer completed and the bean was fully added to the bean store? I looked through the sources but I was not able to find anything.
I'm using WELD 2.3.5.final on WildFly 10.1
You need to detail several things, and one of the most important one is scope, and at what point is the bean needed?
Obviously if there is an observer method that listens to this bean event, and also needs a reference to this bean in the observer parameter, then you are definitely creating a cyclic dependency, which you cannot resolve, as the events in CDI are synchronous by default (And even if you use the fireAsync, there is no guarantee that by the time the event arrive, CDI has put the bean into proper context)
I would solve this problem by doing a method injection on an eargerly loaded bean such as ejbs Singleton or #ApplicationScoped with some kind of earger loading, and then fire the event from there.
Assuming that the bean is eargerly loaded:
public class EargerBean {
#Inject
private Event<BeanEvent> event;
#Inject
public void onInjected(Bean bean){
BeanEvent beanEvent ...;
event.fire(beanEvent);
}
}
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.
In our project, we use Spring request scoped beans. Now we've a requirement to support async requests and request scoped beans don't work for child threads. I'm aware of RequestContextFilter and it's "support" for async but it appears that RequestContextFilter expects the main thread to wait for the child threads to finish, which isn't the case for us. Our main thread immediately returns after spawning new threads using #Async annotation and DispatcherServlet clears out the RequestContextHolder. Thus when the child threads get to the point where they need a request scoped bean, #Autowired fails.
I'm also aware of SimpleThreadScope but it doesn't clean up thread-local attributes and in a thread-pooling situation, is not only dangerous to use but downright useless.
What I need is a custom scope. So far, I've found 3 useful examples but all of them fall short in that the beans they instantiate as part of the custom scope are plain POJOs without any dependencies. Needless to say that's non-existent in a real life application. Can anyone suggest a way to instantiate custom scoped beans that have #Autowired dependencies on beans from other scopes?
What I found so far:
https://github.com/spring-by-example/spring-by-example/tree/master/modules/sbe-thread-scope/src/main/java/org/springbyexample/bean/scope/thread
https://github.com/billkoch/spring-async-mdc
Spring Bean Custom Scope JMS
Continuing the discussion from the other question's answer here...
See the Spring Documentation about scoped beans as dependencies.
.
I'm referring to the <aop:scoped-proxy/> which is what the link points to. Each time the autowired field is referenced, your custom scope's get() method is called to lookup the instance based on some criteria.
.
I understand I can look up the dependencies (though unsure how, a scope isn't a bean, perhaps I need to pass application context during instantiation?). What I don't understand is how to inject those dependencies into my bean if those're marked #Autowired? Or are you saying the custom scoped bean shouldn't have #Autowired dependencies?
It works automatically; Spring injects a proxy for the bean and the scope.get() is invoked on every method call on that bean, returning the specific instance you want in the context of the current invocation.
Take a look at the AbstractRequestAttributesScope to see how it works (in that case, gets the instance from the HTTP Request and, if it doesn't exist, creates it).
So, your code calls foo() on the proxy; the framework calls the scope to get the desired instance and then calls foo() on that instance.
The exposed methods you wish to call must either be on an interface or not declared final.