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.