1

I'm trying to create a simple TcpInboundGateway using spring.

But the following does not work:

@EnableIntegration
@IntegrationComponentScan
public class MyEndpoint {
    @Bean
    public TcpInboundGateway gateway() throws Exception {
        TcpInboundGateway gate = new TcpInboundGateway();
        TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
        fact.setType("server");
        fact.setPort(5555);
        gate.setConnectionFactory(fact.getObject());
        gate.setRequestChannel(new RendezvousChannel());
        return gate;
    }
}

Result:

Caused by: org.springframework.beans.factory.FactoryBeanNotInitializedException: org.springframework.integration.ip.config.TcpConnectionFactoryFactoryBean does not support circular references
    at org.springframework.beans.factory.config.AbstractFactoryBean.getEarlySingletonInstance(AbstractFactoryBean.java:164)
    at org.springframework.beans.factory.config.AbstractFactoryBean.getObject(AbstractFactoryBean.java:148)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 31 more

What might be missing here?

membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

4

Change your code to

@Bean
public TcpInboundGateway gateway(AbstractConnectionFactory connectionFactory) throws Exception {
    TcpInboundGateway gate = new TcpInboundGateway();
    gate.setConnectionFactory(connectionFactory);
    gate.setRequestChannel(new RendezvousChannel());
    return gate;
}

@Bean
public TcpConnectionFactoryFactoryBean connectionFactory() {
    TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
    fact.setType("server");
    fact.setPort(5555);
    return fact;
}

Spring has a specific way of handling FactoryBean instances and your gateway bean breaks it by invoking getObject before the TcpConnectionFactoryFactoryBean is initialized (you could also call afterPropertiesSet to initialize inline). With the code above, you let Spring take care of the initialization.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

You misunderstood a bit the JavaConfig concepts. Please, read more Spring Framework Manual Reference.

The answer to your particular case: any FactoryBean must be configured as a separate @Bean and references like method argument injection:

@Bean
public TcpConnectionFactoryFactoryBean connectionFactory() {
    TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
    fact.setType("server");
    fact.setPort(5555);
    return fact;
}

@Bean
public TcpInboundGateway gateway(AbstractConnectionFactory connectionFactory) throws Exception {
   TcpInboundGateway gate = new TcpInboundGateway();
   gate.setConnectionFactory(connectionFactory);
   gate.setRequestChannel(new RendezvousChannel());
   return gate;
}

As well as the RendezvousChannel as a bean from you separate question: How to create channels with Spring 4 annotation based?.

Community
  • 1
  • 1
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118