2016-02-08 30 views
0

我正在使用Spring集成來解析XML文件,我需要爲每個標記創建一個線程(並且每個都有不同的速率)。彈簧集成 - 從配置文件調度作業

現在(在這裏的許多用戶:)的幫助下)我能夠通過標記拆分XML,然後將其路由到合適的service-activator

這很好,但我無法重定向到創建「一個線程」,然後執行操作的通道。現在,我有以下的配置,並在我的心(我不知道它是否是正確的......)

Split tag -> Route to the appropiate channel -> Start a thread(from tag configuration) -> Execute the operation 

這是我的實際配置是分裂標記並重定向到該通道。 路由器不應直接重定向到頻道,而是安排它們。

在第一個例子中,我們可以將它重定向到固定速率的池中,稍後我將使用XPATH獲取屬性,然後用正確的值替換這個「固定」速率。

我已經嘗試了許多解決方案來創建這個流程,但是每一個失敗或不進行編譯:(

<context:component-scan base-package="it.mypkg" /> 

<si:channel id="rootChannel" /> 

<si-xml:xpath-splitter id="mySplitter" input-channel="rootChannel" output-channel="routerChannel" create-documents="true"> 
    <si-xml:xpath-expression expression="//service" /> 
</si-xml:xpath-splitter> 

<si-xml:xpath-router id="router" input-channel="routerChannel" evaluate-as-string="true"> 
    <si-xml:xpath-expression expression="concat(name(./node()), 'Channel')" /> 
</si-xml:xpath-router> 

<si:service-activator input-channel="serviceChannel" output-channel="endChannel"> 
    <bean class="it.mypkg.Service" /> 
</si:service-activator> 

UPDATE: 使用這種配置的service這應該運行任務每10秒(該id=service1),並每5秒另一個(id=service2)。以同樣的方式,我可以有一個由另一個類處理(因爲這將有另一個行爲),另一個標籤

<root> 
    <service id="service1" interval="10000" /> 
    <service id="service2" interval="5000" /> 
    <activity id="activity1" interval="50000" /> 
<root> 

我將有一個類(Service),通常處理服務標籤,並完成一些操作,然後「返回我」值,以便我可以重定向到另一個通道。

public class Service { 
    public int execute() { 
     // Execute the task and return the value to continue the "chain" 
    } 
} 

回答

0

這並不完全清楚你的意思;你分開一個標籤;路由它,但想要以XML中的速率「安排」它。目前還不清楚你在這裏的「時間表」是什麼意思 - 通常每個消息按照時間表處理一次而不是多次。

正如我所說,我不明白你需要做什麼,但smart poller可能是合適的。

另一種可能性是delayer其中延遲量可以從消息中導出。

編輯

因爲你的「服務」似乎沒有采取任何輸入數據時,它看起來像你只需要配置/啓動每個服務的<inbound-channel-adapter/>,然後再啓動它的基礎上, XML中的參數。

<int:inbound-channel-adapter id="service1" channel="foo" 
      auto-startup="false" 
      ref="service1Bean" method="execute"> 
    <poller fixed-delay="1000" /> 
</int:inbound-channel-adapter/> 

auto-startup="false"。現在

,在接收分

@Autowired 
SourcePollingChannelAdapter service1; 

... 

public void startService1(Node node) { 

    ... 

    service1.setTrigger(new PeridicTrigger(...)); 

    service1.start(); 

    ... 
} 
+0

我知道有點難以解釋我必須做什麼......但是我已經用一個小例子更新了我的問題。現在我會看看你的鏈接 – Mistre83

+0

我想到的是「拆分」標籤並提取間隔。此間隔將需要提交任務(由ScheduledExecutorService - scheduleAtFixedRate完成) – Mistre83

+0

請參閱我對一個解決方案的編輯。 –

0

我不知道這是否是實現流量的正確方法,但我已經寫了如下的代碼代碼:

的applicationContext.xml

<context:component-scan base-package="it.mypkg" /> 

<!-- Expression to extract interval from XML tag -->  
<si-xml:xpath-expression id="selectIntervalXpath" expression="//*/@interval" /> 

<si:channel id="rootChannel" /> 

<!-- Split each tag to redirect on router --> 
<si-xml:xpath-splitter id="mySplitter" input-channel="rootChannel" output-channel="routerChannel" create-documents="true"> 
    <si-xml:xpath-expression expression="//service|//activity" /> 
</si-xml:xpath-splitter> 

<!-- Route each tag to the appropiate channel --> 
<si-xml:xpath-router id="router" input-channel="routerChannel" evaluate-as-string="true"> 
    <si-xml:xpath-expression expression="concat(name(./node()), 'Channel')" /> 
</si-xml:xpath-router> 

<!-- Activator for Service Tag --> 
<si:service-activator input-channel="serviceChannel" method="schedule"> 
    <bean class="it.mypkg.Service" /> 
</si:service-activator> 

<!-- Activator for Activity Tag --> 
<si:service-activator input-channel="activityChannel" method="schedule"> 
    <bean class="it.mypkg.Activity" /> 
</si:service-activator> 

<!-- Task scheduler --> 
<task:scheduler id="taskScheduler" pool-size="10"/> 

每個標籤將延長一個Operation類(以避免在注射豆代碼重複)

Operation.java

public abstract class Operation { 

    protected TaskScheduler taskScheduler; 
    protected XPathExpression selectIntervalXpath; 

    abstract public void schedule(Node document); 

    @Autowired 
    public void setTaskScheduler(TaskScheduler taskScheduler) { 
     this.taskScheduler= taskScheduler; 
    } 

    public TaskScheduler getTaskScheduler() { 
     return this.taskScheduler; 
    } 

    @Autowired 
    public void setSelectIntervalXpath(XPathExpression selectIntervalXpath) { 
     this.selectIntervalXpath = selectIntervalXpath; 
    } 

    public XPathExpression getSelectIntervalXPath() { 
     return this.selectIntervalXpath; 
    } 
} 

和服務類的一個實例(即處理提供的.xml的所有標籤service

public class Service extends Operation { 

    private static final Logger log = Logger.getLogger(Service.class); 

    @Override 
    public void schedule(Node document) { 
     log.debug("Scheduling Service"); 
     long interval = Long.parseLong(this.selectIntervalXpath.evaluateAsString(document)); 

     this.taskScheduler.scheduleAtFixedRate(new ServiceRunner(), interval); 
    } 

    private class ServiceRunner implements Runnable { 

     public void run() { 
      log.debug("Running..."); 

     } 
    } 
} 

現在繼續我的流程,我將需要找到一種方法來重定向每個作業的輸出到Spring集成(applicationContext.xml)。