当前位置: 首页 > 知识库问答 >
问题:

在Spring集成中动态创建服务激活器

贺福
2023-03-14

我有一个Web服务,每个版本将有多个版本和多个类。我想在启动时动态创建服务激活器,这样我就可以减少配置量,从而更容易维护。开发人员可以放入一个新类,SI会自动拾取它。

我编码了一个Application Listener:

public class SpringContextListener implements ApplicationListener<ContextRefreshedEvent> {
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("ApplicationListener Invoked At Spring Container Startup");

                String s = "com.ps.snt.MyClass";
                Class c = Class.forName(s);

                ServiceActivatingHandler serviceActivator;
                serviceActivator = new ServiceActivatingHandler(c.newInstance());
                serviceActivator.setComponentName("MyClassBean");
                // also tried setBeanName
        }
}

稍后在路由器中,我有以下代码:

protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {

        List<MessageChannel> channels = new ArrayList<MessageChannel>();

        MessageChannel channel = (MessageChannel)this.getBeanFactory().getBean("MyClassBean", ServiceActivatingHandler.class);
        channels.add(channel);
        return channels;
    }

但当路由器尝试路由时,我会出现以下错误:

 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyClassBean' is defined

我该怎么做?我需要动态创建服务激活器,并在以后将消息路由到这些激活器。

<int:service-activator input-channel="MyClassBean">
        <bean class="com.ps.snt.ws.MyClassBean" />
    </int:service-activator>

没有办法在ServiceActivatingHandler上设置输入通道,所以我需要创建一个同名通道并订阅激活器吗?这是代码,仍然收到相同的错误:

String s = "com.ps.snt.MyClass";
Class c = Class.forName(s);

DirectChannel channel = new DirectChannel();
channel.setBeanName("MyClassBean");

ServiceActivatingHandler serviceActivator;
serviceActivator = new ServiceActivatingHandler(c.newInstance());

channel.subscribe(serviceActivator);

更新:我必须在创建通道后注册bean。这段代码成功了:

DirectChannel channel = new DirectChannel();
channel.setBeanName("MyClassBean");

ServiceActivatingHandler serviceActivator;
serviceActivator = new ServiceActivatingHandler(c.newInstance());

channel.subscribe(serviceActivator);

ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) context).getBeanFactory();
beanFactory.registerSingleton("MyClassBean", channel);

我的新问题是:这是一种可行的方法,还是会导致后续问题?

共有1个答案

朱昊乾
2023-03-14

如果它应该是动态/运行时的,那么您就不会硬编码SA bean类名。

如果您可以对您的部署和运行时环境提出一些见解,也许我可以提出更好的方法。您的目标不明确(开发人员可以放弃SA类,SI会自动获取它)。

 类似资料:
  • 我有一个队列通道和一个带有轮询器的服务激活器,轮询器从该队列中读取数据。我希望配置为“我希望50个线程轮询该队列,每次轮询并返回消息时,在此线程上调用服务激活器指向的服务。” 该服务没有异步注释,但无状态,可以以并发方式安全运行。 下面的方法能做到吗?有没有其他首选的方法来实现这一点?

  • 我在一个简单的POJO中配置了一个服务激活器,我想将其转换为Java DSL。 现在,我的Java DSL如下所示, 有一个带有服务激活器的POJO, 在XML中,相应的配置如下所示, 如何在Java DSL中调用ServiceActivator方法?我正在考虑使用,但参数应该是什么 在使用Java DSL时,是否有空通道的概念?如果是,我们如何指定

  • 我有一个非常简单的集成流程: 服务激活器调用的方法尝试将消息中的数据与数据库中的某些数据相匹配。如果是,则返回匹配的数据。如果没有,它将返回。 如果我没有设置必需回复为真,那么回复似乎会从集成流中消失,导致服务接口永远不会返回,从而导致应用程序挂起。如果我设置了必需回复为真,我至少会得到一个异常,但是应用程序仍然挂起,因为网关的服务接口永远不会返回: spring集成参考资料中似乎没有记录这种行为

  • 我试图从Spring集成示例中转换“Hello World示例”(https://github.com/spring-projects/spring-integration-samples/tree/master/basic/helloworld)从XML到Java配置(使用注释也是如此)。 配置类如下所示: 为了测试它,我使用示例项目提供的: 我在控制台中看到“Message payload:t

  • 如何在我的项目中动态创建以轮询和检索服务器中的文件?

  • 单击通知、服务创建新活动和活动创建新服务? 我的应用MainActivity“OnCreate”创建一个“粘性”的服务。 在我的服务中,当有一些通知时,我会发布多个通知。除非用户进入应用程序并阅读通知,否则通知将在那里。在onStartCommand中检查新通知。 按下通知将发送打开MainActivity的意图。 有服务、主要活动和通知。 一段时间后,MainActivity被系统杀死。 单击通