我正在使用Spring-Boot开发一个Spring-Batch项目,一切都顺利进行.我已经完成了一些春季批量示例(包括一些来自spring.io),但我不确定其中的一些内容是什么,"它只是有效"并不能满足我的需求.
我的spring boot主类实现了CommandLineRunner,对于这个特定的工作,初始设置看起来像
@Bean
public Job myJob(JobExecutionListenerSupport listener) {
return myJobBuilderFactory.get(JOB)
.listener(listener)
.start(myStep())
.build();
}
Run Code Online (Sandbox Code Playgroud)
哪个引起了
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:790) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:777) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.bjc.providermodel.maintenance.MaintenanceApplication.main(MaintenanceApplication.java:20) [classes/:?]
Caused by: org.springframework.batch.core.repository.JobExecutionAlreadyRunningException: A job execution for this job is already running: JobInstance: id=99, version=0, Job=[myJob]
Run Code Online (Sandbox Code Playgroud)
为什么要将上面的bean更改为
@Bean
public Job myJob(JobExecutionListenerSupport listener) {
return myJobBuilderFactory.get(JOB)
.incrementer(new RunIdIncrementer())
.listener(listener)
.start(myStep())
.build();
}
Run Code Online (Sandbox Code Playgroud)
让一切顺利吗?我试图阅读文档,RunIdIncrementer并在此处阅读一些内容.从我可以告诉它需要这个增量器来跟踪正在运行的特定工作集来做"东西",但不确定究竟是什么东西.Spring-Boot抽象让我很难知道这里发生了什么
我有一个名单列表,我需要输出一个字符串,按照它们出现的顺序显示名称中的字母而不重复(例如,如果列表是["John"; "James"; "Jack"],输出字符串应该是Johnamesck).我有一个解决方案(将所有名称折叠成一个字符串,然后解析),但我觉得我通过使我的字符串变得可变来讨厌它.
我也想说明这不是一个作业,刚刚从工作同事的锻炼,因为我进入F#从永远只知道的Java Web的东西.
这是我的工作解决方案(用于洞察目的):
let lower = ['a' .. 'z']
let upper = ['A' .. 'Z']
let mutable concatedNames = ["John"; "James"; "Jack"] |> List.fold (+) ""
let greaterThanOne (length : int) = length > 1
let stripChars (str : string) letter =
let parts = str.Split([| letter |])
match greaterThanOne (Array.length parts) with
| true -> seq {
yield Array.head parts
yield string letter
yield! Array.tail parts
}
|> String.concat ""
| _ …Run Code Online (Sandbox Code Playgroud) 几个月前,我在这篇文章中提出了基本相同的要求:Spring JMS侦听器应如何处理有效负载为空的消息?,但是我得到的只是一个微不足道的评论,暗示我“重写我的监听器以执行我想要的事情”。有效的声明,但在我眼中仍不清楚,因为我仍在使用Spring-Boot。从那时起我就学会了,并且想更直接地重新提出这个问题(而不是在老问题上悬赏)。
我使用@Configuration和设置了一个带注释的bean类,@EnableJms我的容器工厂如下所示:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(mqConnectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("1");
factory.setErrorHandler(errorHandler());
factory.setSessionTransacted(true);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}
Run Code Online (Sandbox Code Playgroud)
监听器看起来像:
@JmsListener(id = "qID", destination = "qName")
public void processOrder(String message) {. . .}
Run Code Online (Sandbox Code Playgroud)
据我了解,一旦带注释的Bean类运行完毕,JMSListener基本上就开始了(除非我设置autoStartup为false),所以我无法理解何时何地可以控制什么或如何JmsListener处理事物。在我看来,它“运行”。因此,如果队列上有一个队列"\n"或只有一个空字符串,则侦听器将引发异常。具体来说org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class java.lang.String。而且这个异常被抛在了后面。我从来没有机会在监听器中执行任何操作
我看着SimpleMessageConverter但似乎没有什么可以让我说出类似的话setIgnoreStringPattern()。那显然不存在,但这就是我所需要的。我想念什么?有没有办法告诉JmsListener忽略某些字符串?
有没有特定的方法可以做到这一点?我试图在此处找到解决方案,但找不到我需要的东西。我有一个Spring Boot应用程序,它将从命令行接受多个参数。有问题的参数是队列名称(即目的地)。它可以是我们众多队列中的几个。该JmsListener是形式
@JmsListener(destination="dest_goes_here")
public void processOrder(Message message){. . .}
Run Code Online (Sandbox Code Playgroud)
我有一堂课基本上是这样的
public class Arguments {
private static queue
private static antoherArg
:
:
getters and setters
}
Run Code Online (Sandbox Code Playgroud)
我想说的是destination = Arguments.getQueue(),但似乎destination只能是一个static final变量?我认为这是因为错误提供了一些暗示这一点的工具提示。
我还测试了它,因为我还有另一个名为的类Constants,它包含常量,如果我用硬编码对队列名称进行编码,public static final String QUEUE = "MyQ";则说destination = Constants.QUEUE可以。
因此,我以为我可以在我的侦听器类中做类似的事情,private static final String QUEUE = Arguments.getQueue();但这也不是那样。las,我很沮丧。
因此,如果有人愿意分享知识,那么这里确实有两个问题。为什么@JmsListener用确定已经destination设置为我的第二个解决方案,但不是第一个和最后一个?
然后,主要的问题(我希望您比第一个回答)是,我可以使用哪些策略将目标设置为源自命令行的变量(即动态变量)?
编辑:澄清一下,我不能将值保留在我的Constants类中,因为该值将来自命令行,并且需要传递给JmsListener类以用作destination。
我的项目正在处理正在写入excel文件的大量数据。我将此数据存储在一个静态HashMap中,其形式Map<List<String>, Integer>为,列表的大小仅为3。但是,Map中的条目数范围可以从0到11,300。
该项目的流程为:
使用条目加载地图
迭代地图并执行操作
我最近发现的有关HashMap的信息是,当违反设置的大小时,它将如何重新调整大小。因此,不仅我的地图会不断调整其大小,而且在我清除最大的一组条目时,它很可能会有大约20,000个空条目。
因此,我正在尝试对该事物进行微优化,并且在执行此操作时遇到了两难选择。我的两个想法是:
将初始HashMap的默认值设置为一个值,该值最多只能调整一次
使用每个新条目集的平均大小重新初始化HashMap,以限制重新调整大小并允许垃圾收集器进行一些清理
我的直觉告诉我,选项2可能是最合理的选择,但这仍然可以证明需要根据下一个条目集进行大量调整。但是,选项一极大地限制了一次操作的大小调整,但是实际上留下了成千上万个空条目。
我提出的两个解决方案中的一个是否比另一个更好,或者两者之间在内存改进方面没有太大区别,还是我可以监督其他解决方案(不涉及更改数据结构)?
编辑:仅在某些情况下,我想这样做,因为项目偶尔会用完堆内存,并且我试图确定此巨大映射的影响程度是多少。
EDIT2:只是为了澄清,地图本身的大小是较大的值。密钥大小(即列表)永远只有3。