Manuel Jordan opened SPR-17139 and commented
I have the following situation about FactoryBean
for the getObject()
execution.
I have for example:
@Bean
ActiveMQConnectionFactoryFactoryBean connectionFactoryInstanceARemoteHostFactoryBean(){
logger.info("@Bean connectionFactoryInstanceARemoteHostFactoryBean ...");
ActiveMQConnectionFactoryFactoryBean factoryBean = new ActiveMQConnectionFactoryFactoryBean();
....
logger.info(" {}", factoryBean.toString());
return factoryBean;
}
Where:
public class ActiveMQConnectionFactoryFactoryBean implements FactoryBean<ActiveMQConnectionFactory>{
...
@Override
public ActiveMQConnectionFactory getObject() throws Exception {
...
}
}
From above:
* The @Bean
method is created/managed by Spring
* In other @Bean
method that works with @Conditional
I can call and execute manually the getObject()
method.
Until here all work how is expected.
My problem is with RabbitMQ
, I have the following:
@Bean
RabbitMQCachingConnectionFactoryFactoryBean cachingConnectionFactoryInstanceARemoteHostFactoryBean() {
logger.info("@Bean cachingConnectionFactoryInstanceARemoteHostFactoryBean ...");
RabbitMQCachingConnectionFactoryFactoryBean factoryBean = new RabbitMQCachingConnectionFactoryFactoryBean();
...
logger.info(" {}", factoryBean.toString());
return factoryBean;
}
and
public class RabbitMQCachingConnectionFactoryFactoryBean implements FactoryBean<CachingConnectionFactory> {
...
@Override
public CachingConnectionFactory getObject() throws Exception {
Thus the following:
* The @Bean
method is created/managed by Spring
* In other @Bean
method that works with @Conditional
I can call and execute manually the getObject()
method.
When @Conditional
is false that other @Bean
never calls and execute manually the getObject()
method. It is expected.
Problem: but because implements FactoryBean<ActiveMQConnectionFactory>
works with ActiveMQConnectionFactory
and it is declared how:
@ManagedResource
public class CachingConnectionFactory extends AbstractConnectionFactory
implements InitializingBean, ShutdownListener, PublisherCallbackChannelConnectionFactory {
I did realise that because the component is marked with @ManagedResource
, Spring through JMX, calls automatically the getObject()
method. Arising errors.
I have the following:
@Configuration
@EnableMBeanExport
public class JmxConfig {
}
If I comment @EnableMBeanExport
the app starts up without problem. But I need use JMX for other components, I need Spring does not execute automatically that @ManagedResource
.
This behaviour about JMX triggers automatically the getObject()
method when the FactoryBean
's type is marked with @ManagedResource
(i.e: CachingConnectionFactory
) is not covered neither 1.8.3. Customizing instantiation logic with a FactoryBean nor 4. JMX
Affects: 5.0.8
Comment From: spring-projects-issues
Manuel Jordan commented
Is it the expected behavior?
With the current API what is the best approach to avoid this situation?
Thank you.
Comment From: jhoeller
The common solution here is to declare the target bean definition as lazy-init. The MBeanExporter
takes that into account already. I'll document that in the JMX chapter.