-
Notifications
You must be signed in to change notification settings - Fork 40.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConditionalOnBean not working well with JMS Connection Factory #39602
Comments
Thanks for getting in touch, but this issue tracker is dedicated to bugs an enhancement requests. As you already know,
All of those use cases are invalid. I've reported an issue to one of them, feel free to do so for other sources.
As for this case, it is probably because you've left your configuration to be scanned in your main application package. There is a note about this on our reference documentation:
Moving your configuration class to a different package: package org.zighinetto.autoconfigure;
import jakarta.jms.ConnectionFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.jms.dsl.Jms;
@AutoConfiguration(after = JmsAutoConfiguration.class)
public class IntegrationFlowAutoConfiguration {
@ConditionalOnBean(ConnectionFactory.class)
@Bean
public IntegrationFlow exampleIntegrationFlow(ConnectionFactory connectionFactory) {
return IntegrationFlow.from(Jms.inboundAdapter(connectionFactory)
.destination("entry")
)
.transform(String.class, String::toUpperCase)
.handle(Jms.outboundAdapter(connectionFactory)
.destination("exit")
)
.get();
}
} Declaring it in
Yields the following in the auto-configuration report (when starting your application with the DEBUG property):
|
Please see POC repository on Github
I am having a hard time defining a
@ConditionalOnBean(jakarta.jms.ConnectionFactory.class)
bean for some Spring Integration Flows that depend on the availability of a JMS connection. I have read the documentation (linked below) that@ConditionalOnBean
must/should be used only onAutoConfiguration
classes, but I insist on using it on regular beans like linked sources do.I only need to define an IntegrationFlow as soon as the ConnectionFactory exists. If the application is started without a JMS broker (e.g. is not configured) then it should reduce its functionality and not initialize the relative
IntegrationFlow
s. I have it over-simplified in my POC, as the real application contains around 120 integration flows and interacts with a handful of JMS channels.Expectation: the provided JUnit test should invoke the flow using JMS and get the reply back. Commenting out the
@ConditionalOnBean
annotation fixes the testI am opening an issue here instead of an SO question because ConditionalOnBean annotation is working perfectly in any other case, and I can't tell Spring to load my configuration class after JMS
In the POC repository, we define an example
IntegrationFlow
that:entry
JMS channelexit
JMS channelThe IntegrationFlow depends on the
jakarta.jms.ConnectionFactory
to have been defined as a bean. In my business case, the Spring Boot application may start without JMS at all, so the IntegrationFlow must not be defined.For that purpose, we use the
@ConditionalOnBean
annotation.Per Spring documentation, that annotation should be used only on
@AutoConfiguration
classes, which makes things a little more complicated.Half of the world uses the same annotation for a variety of purpose, and we are actively using it in our real application to instantiate a bean only if a collaborator is defined as a bean. None of these require that one uses
@ConditionalOnBean
on@AutoConfiguration
s onlyTo provide an example, we use a number of _RestService_s that depend on
RestTemplate
(bearing the root url and authentication info), as well as _SoapService_s depending onWebServiceTemplate
, and they depend as such:WebServiceTemplate
bean depends on business propertycom.example.ws.{url|username|password}
@ConditionalOnBean(value = WebServiceTemplate.class, name = "mySpecificWebServiceTemplateBecauseWeHavePlentiesOf")
All beautiful, except that it doesn't work with JMS ConnectionFactory. In this case, the connection factory exists only if
spring.artemis.embedded=true
(or another MQ broker is defined according to profile configuration).In this POC, I can see that Spring refuses to instantiate the IntegrationFlow despite the ConnectionFactory exists.
Other considerations:
@Configuration
classes@AutoConfiguration(after = JmsAutoConfiguration.class)
did not work@DependsOn("jmsConnectionFactory")
fails when there is no JMS ConnectionFactoryMyJmsConfiguration
does not match the ConditionArtemisAutoConfiguration
, the ConnectionFactory eventually is createdBeanFactory
, the ConnectionFactory bean is eventually available@SpringIntegrationTest
is currently not present in the POC but makes no difference (the real application shows it)The text was updated successfully, but these errors were encountered: