Java Spring集成:Dispatcher没有通道';未知.channel.name';
让我先说一下,我让这段代码正常工作,但我做了一些事情,无论如何都无法让它正常工作 我正在编写一个专门使用Java配置的小型Spring集成应用程序 以下是我收到错误时的日志:Java Spring集成:Dispatcher没有通道';未知.channel.name';,java,spring,Java,Spring,让我先说一下,我让这段代码正常工作,但我做了一些事情,无论如何都无法让它正常工作 我正在编写一个专门使用Java配置的小型Spring集成应用程序 以下是我收到错误时的日志: pool-3-thread-2 || INFO o.s.i.e.EventDrivenConsumer || Adding {bridge:null} as a subscriber to the 'null' channel pool-3-thread-2 || INFO o.s.i.c.DirectChannel
pool-3-thread-2 || INFO o.s.i.e.EventDrivenConsumer || Adding {bridge:null} as a subscriber to the 'null' channel
pool-3-thread-2 || INFO o.s.i.c.DirectChannel || Channel 'unknown.channel.name' has 1 subscriber(s).
pool-3-thread-2 || INFO o.s.i.e.EventDrivenConsumer || started org.springframework.integration.endpoint.EventDrivenConsumer@282097a6
pool-3-thread-2 || DEBUG o.s.b.f.s.DefaultListableBeanFactory || Returning cached instance of singleton bean 'integrationGlobalProperties'
pool-3-thread-2 || DEBUG o.s.i.c.DirectChannel || preSend on channel 'org.springframework.integration.channel.DirectChannel@6d16efa2', message: GenericMessage [payload=byte[244], headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@36ebee89, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@36ebee89, ip_tcp_remotePort=42432, ip_connectionId=localhost6.localdomain6:42432:8080:c93ee59a-17e3-4c19-98a5-6bb374652181, ip_localInetAddress=/0:0:0:0:0:0:0:1, ip_address=0:0:0:0:0:0:0:1, id=54cbd13c-bb4b-0986-8bc1-93d436884be7, ip_hostname=localhost6.localdomain6, timestamp=1460066984381}]
pool-3-thread-2 || DEBUG o.s.i.i.t.TcpInboundGateway || failure occurred in gateway sendAndReceive: Dispatcher has no subscribers for channel 'unknown.channel.name'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
pool-3-thread-2 || ERROR o.s.i.i.t.c.TcpNetConnection || Exception sending message: GenericMessage [payload=byte[244], headers={ip_tcp_remotePort=42432, ip_connectionId=localhost6.localdomain6:42432:8080:c93ee59a-17e3-4c19-98a5-6bb374652181, ip_localInetAddress=/0:0:0:0:0:0:0:1, ip_address=0:0:0:0:0:0:0:1, id=972d1c96-238a-2598-b488-50c00710f12b, ip_hostname=localhost6.localdomain6, timestamp=1460066984373}]
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'unknown.channel.name'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42)
at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97)
at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:422)
at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:390)
at org.springframework.integration.ip.tcp.TcpInboundGateway.doOnMessage(TcpInboundGateway.java:119)
at org.springframework.integration.ip.tcp.TcpInboundGateway.onMessage(TcpInboundGateway.java:97)
at org.springframework.integration.ip.tcp.connection.TcpNetConnection.run(TcpNetConnection.java:182)
at java.util.concurrent.ThreadPoolExecutor.runWorkadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
... 14 common frames omitted
最令人困惑的部分是unknown.channel.name部分。我不知道这是从哪里来的,在错误发生之前,日志中没有提到过一次
有两个类利用Spring集成:
AppConfig.java
package com.acme.project.spring;
@EnableAutoConfiguration
@EnableIntegration
@IntegrationComponentScan
@Configuration
@PropertySource(name = "props", value = "classpath:/application.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean(name = "inputChannel")
public static MessageChannel inputChannel() {
return new DirectChannel();
}
@Bean(name = "handlerChannel")
public static MessageChannel handlerChannel() {
return new DirectChannel();
}
@Bean(name = "replyChannel")
public static MessageChannel replyChannel() {
return new DirectChannel();
}
@MessagingGateway(defaultRequestChannel = "handlerChannel")
public interface Gateway {
String send(String request);
}
@Bean(name = "inputGateway")
public TcpInboundGateway inputGateway(AbstractServerConnectionFactory connectionFactory) {
LOGGER.info("get inputGateway");
TcpInboundGateway gw = new TcpInboundGateway();
gw.setConnectionFactory(connectionFactory);
gw.setRequestChannel(inputChannel());
gw.setReplyChannel(replyChannel());
return gw;
}
@Bean(name = "serverFactory")
public AbstractServerConnectionFactory serverFactory() {
Integer port = Integer.parseInt(env.getProperty("portNumber"));
AbstractServerConnectionFactory factory = new TcpNetServerConnectionFactory(port);
factory.setSerializer(serializer());
factory.setDeserializer(deserializer());
return factory;
}
@Transformer(inputChannel = "replyChannel")
public String convertFromMyObject(MyObject obj) {
...
return obj.toString();
}
@Transformer(inputChannel = "inputChannel")
public MyObject convertToMyObject(byte[] bytes) {
...
return new MyObject(bytes);
}
@Bean(name="serializer")
public Serializer serializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "deserializer")
public Deserializer deserializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "a")
public A getA() {
return new A();
}
@Bean(name = "b")
public B getB() {
return new B();
}
}
package com.acme.project.spring;
@MessageEndpoint
public class Handler {
@Autowired
private A a;
@Autowired
private B b;
@ServiceActivator(inputChannel = "handlerChannel", outputChannel = "replyChannel")
public MyObject handle(MyObject request) {
MyObject response = new MyObject();
...
return response;
}
public void setA(A a) {
this.a = a;
}
public void setB(B b) {
this.b = b;
}
}
public class Main {
public static void main(String... args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.acme.project.spring");
ctx.registerShutdownHook();
}
}
========
Handler.java
package com.acme.project.spring;
@EnableAutoConfiguration
@EnableIntegration
@IntegrationComponentScan
@Configuration
@PropertySource(name = "props", value = "classpath:/application.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean(name = "inputChannel")
public static MessageChannel inputChannel() {
return new DirectChannel();
}
@Bean(name = "handlerChannel")
public static MessageChannel handlerChannel() {
return new DirectChannel();
}
@Bean(name = "replyChannel")
public static MessageChannel replyChannel() {
return new DirectChannel();
}
@MessagingGateway(defaultRequestChannel = "handlerChannel")
public interface Gateway {
String send(String request);
}
@Bean(name = "inputGateway")
public TcpInboundGateway inputGateway(AbstractServerConnectionFactory connectionFactory) {
LOGGER.info("get inputGateway");
TcpInboundGateway gw = new TcpInboundGateway();
gw.setConnectionFactory(connectionFactory);
gw.setRequestChannel(inputChannel());
gw.setReplyChannel(replyChannel());
return gw;
}
@Bean(name = "serverFactory")
public AbstractServerConnectionFactory serverFactory() {
Integer port = Integer.parseInt(env.getProperty("portNumber"));
AbstractServerConnectionFactory factory = new TcpNetServerConnectionFactory(port);
factory.setSerializer(serializer());
factory.setDeserializer(deserializer());
return factory;
}
@Transformer(inputChannel = "replyChannel")
public String convertFromMyObject(MyObject obj) {
...
return obj.toString();
}
@Transformer(inputChannel = "inputChannel")
public MyObject convertToMyObject(byte[] bytes) {
...
return new MyObject(bytes);
}
@Bean(name="serializer")
public Serializer serializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "deserializer")
public Deserializer deserializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "a")
public A getA() {
return new A();
}
@Bean(name = "b")
public B getB() {
return new B();
}
}
package com.acme.project.spring;
@MessageEndpoint
public class Handler {
@Autowired
private A a;
@Autowired
private B b;
@ServiceActivator(inputChannel = "handlerChannel", outputChannel = "replyChannel")
public MyObject handle(MyObject request) {
MyObject response = new MyObject();
...
return response;
}
public void setA(A a) {
this.a = a;
}
public void setB(B b) {
this.b = b;
}
}
public class Main {
public static void main(String... args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.acme.project.spring");
ctx.registerShutdownHook();
}
}
Main.java
package com.acme.project.spring;
@EnableAutoConfiguration
@EnableIntegration
@IntegrationComponentScan
@Configuration
@PropertySource(name = "props", value = "classpath:/application.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean(name = "inputChannel")
public static MessageChannel inputChannel() {
return new DirectChannel();
}
@Bean(name = "handlerChannel")
public static MessageChannel handlerChannel() {
return new DirectChannel();
}
@Bean(name = "replyChannel")
public static MessageChannel replyChannel() {
return new DirectChannel();
}
@MessagingGateway(defaultRequestChannel = "handlerChannel")
public interface Gateway {
String send(String request);
}
@Bean(name = "inputGateway")
public TcpInboundGateway inputGateway(AbstractServerConnectionFactory connectionFactory) {
LOGGER.info("get inputGateway");
TcpInboundGateway gw = new TcpInboundGateway();
gw.setConnectionFactory(connectionFactory);
gw.setRequestChannel(inputChannel());
gw.setReplyChannel(replyChannel());
return gw;
}
@Bean(name = "serverFactory")
public AbstractServerConnectionFactory serverFactory() {
Integer port = Integer.parseInt(env.getProperty("portNumber"));
AbstractServerConnectionFactory factory = new TcpNetServerConnectionFactory(port);
factory.setSerializer(serializer());
factory.setDeserializer(deserializer());
return factory;
}
@Transformer(inputChannel = "replyChannel")
public String convertFromMyObject(MyObject obj) {
...
return obj.toString();
}
@Transformer(inputChannel = "inputChannel")
public MyObject convertToMyObject(byte[] bytes) {
...
return new MyObject(bytes);
}
@Bean(name="serializer")
public Serializer serializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "deserializer")
public Deserializer deserializer() {
return new ByteArrayCrLfSerializer();
}
@Bean(name = "a")
public A getA() {
return new A();
}
@Bean(name = "b")
public B getB() {
return new B();
}
}
package com.acme.project.spring;
@MessageEndpoint
public class Handler {
@Autowired
private A a;
@Autowired
private B b;
@ServiceActivator(inputChannel = "handlerChannel", outputChannel = "replyChannel")
public MyObject handle(MyObject request) {
MyObject response = new MyObject();
...
return response;
}
public void setA(A a) {
this.a = a;
}
public void setB(B b) {
this.b = b;
}
}
public class Main {
public static void main(String... args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.acme.project.spring");
ctx.registerShutdownHook();
}
}
我认为这很简单。我剥离了所有非Spring部分——特别是业务逻辑等——并简化了一些类名(A/B)。基本上,我有3个通道:inputChannel、replyChannel和handlerChannel。正如我在工作时所理解的,流程是:
serverFactory->serializer->inputChannel->transformer(convertToMyObject)->handlerChannel->ServiceActivator(Handler#handle)->transformer(convertFromMyObject)->replyChannel->返回客户端
任何有助于确定“unknown.channel.name”是什么、是什么导致现在存在以及调度器出了什么问题的帮助都将非常有用。我觉得它应该相对简单——也许是一个混乱的注释——但我就是看不出来
谢谢,我完成Spring集成已经有一段时间了,我只使用XML配置完成了。然而,我无法勾勒出你的流程。作为提示,如果您将服务激活器和转换等放入一个链中,您不必在它们之间连接通道,Spring会为您这样做。我已经完成Spring集成有一段时间了,我只使用XML配置完成了。然而,我无法勾勒出你的流程。作为提示,如果您将服务激活器和转换等放入一个链中,您不必在它们之间连接通道,Spring会为您这样做。