代码之家  ›  专栏  ›  技术社区  ›  pojo-guy

在Spring Batch Integration中,MessageChannelPartitionHandler的javadoc表示要使其成为作业或步骤范围的bean。这在XML中是如何工作的?

  •  0
  • pojo-guy  · 技术社区  · 2 年前

    问题描述:

    在测试中,我意识到我有一个全局作用域的bean“partitionHandler”,类型为o.s.b.I.p.MessageChannelPartitionHandler,需要对其进行步骤作用域处理。

    当我按照xml文件中其他步骤作用域bean的示例进行操作时,由于没有任何步骤作用域的bean处于活动状态,因此无法加载作业。

    通过从bean定义中删除scope=“step”,我可以使我的代码再次发挥作用,但这并不是向前迈出的一步,也无助于我理解前进的根本问题。

    是否有将MessageChannelPartitionHandler作为xml上下文中步骤范围的bean的功能示例?

    (编辑2)

    根本问题似乎是聚合器被定义为全局bean,但它引用的所有bean( am-partitionHandler , am-replyChannel am-aggregatedReplyChannel )是步骤范围的bean。

    <int:aggregator ref="am-partitionHandler"
                    input-channel="am-replyChannel"
                    output-channel="am-aggregatedReplyChannel"/>
    

    (编辑)

    在跟踪代码时:

    • ResourceXmlApplicationContext.preInstantiateSingletonss()正在寻找一个o.s.i.c.AggregatorFactoryBean,它应该是一个单例,然后试图在步骤范围中将其创建为ReleaseStrategyFactoryBean。
    • AbstractBeanFactory.doGetBean()正在名为“step”的作用域中查找名称为“scopedTarget.partitionHandler”的bean,然后引发异常。
    • 在StepSynchronizationManager.getContext()中找不到StepScope,引发根异常

    追逐其他链接时:

    我在之前的一个SE问题中发现了一个几乎相同的符号: Spring Batch - why is the job Step bean is being created/executed in the web context instead of the Job context? 。原始链接描述了在作业执行时加载一个应用程序的问题,而在初始XML上下文加载时(在应用程序启动时),早在bean实际执行之前,spring批处理集成类就会出现这种情况。

    XML片段:

    <bean class="org.springframework.batch.core.scope.JobScope">
        <property name="proxyTargetClass" value="true" />
    </bean>
    
    <bean class="org.springframework.batch.core.scope.StepScope">
        <property name="proxyTargetClass" value="true" />
    </bean>
    
    <bean id="retryListItemWriterListener"
        name="retryListItemWriterListener"
        class="com.myApp.jobscope.RetryListItemWriterListener"
        scope="step" />  <!-- no problems with this and other step scoped beans -->
    
    <int:channel id="aggregatedReplyChannel" scope="step">
        <int:queue/>
    </int:channel>
    
    <bean id="partitionHandler" 
        name="partitionHandler" 
        class="org.springframework.batch.integration.partition.MessageChannelPartitionHandler"
        scope="step"> <!-- step scope breaks this bean at initialization -->
        
        <property name="stepName" value="as-step0002.slave"/>
        <property name="gridSize" value="3"/>  
        <property name="replyChannel" ref="aggregatedReplyChannel"/>
        <property name="jobExplorer" ref="jobExplorer"/>
        <property name="releaseStrategy" ref="releaseStrategy" />
        
        <property name="messagingOperations">
            <bean class="org.springframework.integration.core.MessagingTemplate">
              <property name="defaultChannel" ref="requestsChannel"/>
              <property name="receiveTimeout" value="1000000"/>
            </bean>
        </property>
    </bean>
            
    <batch:job id="eventuallyconsistent-master">
        <batch:step id="am-step0002.master">
            <batch:partition partitioner="flatSourceDataPartitioner" handler="partitionHandler"/> 
            <batch:fail on="FAILED" />  
            <batch:next on="*" to="am-step9998" />
            <batch:listeners>
                <batch:listener ref="flatSourceDataPartitioner" />
                <batch:listener ref="ruleFactory" />
            </batch:listeners>      
        </batch:step>
    </batch:job>
    

    日志剪切:

    main 2023-06-29 10:48:54,050 INFO  o.s.a.f.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.integration.context.IntegrationObjectSupport.afterPropertiesSet()] because it is marked as final: Consider using interface-based JDK proxies instead!
    main 2023-06-29 10:48:54,051 INFO  o.s.a.f.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.integration.context.IntegrationObjectSupport.setBeanName(java.lang.String)] because it is marked as final: Consider using interface-based JDK proxies instead!
    main 2023-06-29 10:48:54,064 INFO  o.s.a.f.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.integration.context.IntegrationObjectSupport.afterPropertiesSet()] because it is marked as final: Consider using interface-based JDK proxies instead!
    main 2023-06-29 10:48:54,065 INFO  o.s.a.f.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.integration.context.IntegrationObjectSupport.setBeanName(java.lang.String)] because it is marked as final: Consider using interface-based JDK proxies instead!
    
    main 2023-06-28 17:08:01,054 ERROR c.m.m.AppInitializer - Failed to start bean 'automaticJobRegistrar'; nested exception is 
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.config.AggregatorFactoryBean#0' defined in file [C:\myApp\jobrepository\eventuallyconsistent-master.xml]: Cannot create inner bean '(inner bean)#5791a9cb' of type [org.springframework.integration.config.ReleaseStrategyFactoryBean] while setting bean property 'releaseStrategy'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#5791a9cb': Invocation of init method failed; nested exception is org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.partitionHandler': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
    org.springframework.context.ApplicationContextException: Failed to start bean 'automaticJobRegistrar'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.config.AggregatorFactoryBean#0' defined in file [C:\jobrepository\eventuallyconsistent-master.xml]: Cannot create inner bean '(inner bean)#5791a9cb' of type [org.springframework.integration.config.ReleaseStrategyFactoryBean] while setting bean property 'releaseStrategy'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#5791a9cb': Invocation of init method failed; nested exception is org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.partitionHandler': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.18.jar:5.3.18]
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.18.jar:5.3.18]
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.18.jar:5.3.18]
        at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.18.jar:5.3.18]
        at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.18.jar:5.3.18]
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.18.jar:5.3.18]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.18.jar:5.3.18]
    
    0 回复  |  直到 2 年前
    推荐文章