本篇文章给大家谈谈Spring-Batch:如何从StepListener返回自定义Job退出代码,以及spring返回文件的知识点,同时本文还将给你拓展2.1SpringBoot启动流程-Sprin
本篇文章给大家谈谈Spring-Batch:如何从StepListener返回自定义Job退出代码,以及spring 返回文件的知识点,同时本文还将给你拓展2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化、ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载、ElastciJobListener && AbstractDistributeOnceElasticJobListener、java – Spring Batch:org.springframework.batch.item.ReaderNotOpenException:读者必须先打开才能读取等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- Spring-Batch:如何从StepListener返回自定义Job退出代码(spring 返回文件)
- 2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化
- ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载
- ElastciJobListener && AbstractDistributeOnceElasticJobListener
- java – Spring Batch:org.springframework.batch.item.ReaderNotOpenException:读者必须先打开才能读取
Spring-Batch:如何从StepListener返回自定义Job退出代码(spring 返回文件)
问题是这样的:我只有一个步骤就能完成一个Spring
Batch作业。此步骤称为多次。如果每次调用它,一切正常(无异常),则作业状态为“已完成”。如果至少在Step的执行之一中发生了问题(抛出异常),我已经配置了一个StepListener,它将退出代码更改为FAILED:
public class SkipCheckingListener extends StepExecutionListenerSupport { public ExitStatus afterStep(StepExecution stepExecution) { String exitCode = stepExecution.getExitStatus().getExitCode(); if (stepExecution.getProcessorSkipCount() > 0) { return new ExitStatus(ExitStatus.FAILED); } else { return null; } }}
当满足条件时,将执行“ if”块,并且作业以FAILED状态结束,这可以正常工作。但是请注意,我在这里返回的退出代码仍在Spring
Batch随附的标准代码中。我想在某些时候返回我的个性化退出代码,例如“ COMPLETED WITH SKIPS”。现在,我尝试更新上面的代码以返回:
public class SkipCheckingListener extends StepExecutionListenerSupport { public ExitStatus afterStep(StepExecution stepExecution) { String exitCode = stepExecution.getExitStatus().getExitCode(); if (stepExecution.getProcessorSkipCount() > 0) { return new ExitStatus("COMPLETED WITH SKIPS"); } else { return null; } }}
如文档中所述:http ://static.springsource.org/spring-
batch/reference/html/configureStep.html(5.3.2.1。批处理状态与退出状态)。我什至尝试过
stepExecution.getJobExecution().setExitStatus("COMPLETED WITH SKIPS");
可以肯定的是,执行到达了“ if”块,执行了代码,但我的工作仍然以退出代码COMPLETED完成,完全忽略了我通过侦听器设置的退出代码。
他们的文档中没有关于此的更多详细信息,而且我还没有使用Google找到任何东西。有人可以告诉我如何以这种方式更改Job退出代码吗?谢谢
答案1
小编典典看起来您只是不能更改BatchStatus,但是可以使用exitstatus尝试
此代码与JobListener对我有用
// JobListener with interface or annotationpublic void afterJob(JobExecution jobExecution) { jobExecution.setExitStatus(new ExitStatus("foo", "fooBar"));}
2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化
返回 SpringApplication 初始化类可以看到这么一句
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
getSpringFactoriesInstances
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
SpringFactoriesLoader
这是一个普通的类 属性有下面三个
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
看到了一个不得了的文件 META-INF/spring.factories,这个文件非常非常重要 很多配置都在这里
spring.factories
看看 springboot 源码里这个文件里都有啥吧
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer
# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
这么一堆 各种熟悉的名词都在这 SpringApplicationRunListener、ApplicationContextInitializer、ApplicationListener、PropertySourceLoader
loadFactoryNames(type, classLoader)
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryClassName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryName = var9[var11];
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
//todo 这个方法暂且不分析了,大体就是从 spring.factories 里根据 key 取 vale 这里涉及到一个概念 SPI(Service provider Interface),具体请看《SpringBoot-SPI 是个什么东东》
内置 Listener
就是文件里这一堆
ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载
ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载内容的区别
一:ContextLoaderListener 加载内容
二:DispatcherServlt 加载内容
ContextLoaderListener 和 DispatcherServlet 都会在 Web 容器启动的时候加载一下 bean 配置。区别在于:
DispatcherServlet 一般会加载 MVC 相关的 bean 配置管理 (如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)
ContextLoaderListener 一般会加载整个 Spring 容器相关的 bean 配置管理 (如: Log, Service, Dao, PropertiesLoader, etc.)
DispatcherServlet 默认使用 WebApplicationContext 作为上下文.
值得注意的是,DispatcherServlet 的上下文仅仅是 Spring MVC 的上下文,而 ContextLoaderListener 的上下文则对整个 Spring 都有效。一般 Spring web 项目中同时会使用这两种上下文.
ElastciJobListener && AbstractDistributeOnceElasticJobListener
esjob监听器的作用是什么?该怎么实现?有没有demo
java – Spring Batch:org.springframework.batch.item.ReaderNotOpenException:读者必须先打开才能读取
我得到了org.springframework.batch.item.ReaderNotOpenException:读者必须打开才能读取异常.
以下是我的配置:
@Bean @StepScope public ItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) { final String [] header = { .. this part omitted for brevity ... }; FlatFileItemReader<Player> reader = new FlatFileItemReader<Player>(); System.out.println("\t\t\t\t\t"+inputZipfile); reader.setResource(new ClassPathResource(inputZipfile)); reader.setLineMapper(new DefaultLineMapper<Player>() {{ setLinetokenizer(new DelimitedLinetokenizer() {{ setNames( header ); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<Player>() {{ settargettype(Player.class); }}); }}); reader.setComments( header ); return reader; } @Bean @StepScope public itemprocessor<Player,PlayeRSStats> processor(@Value("#{jobParameters[statType]}") String statType,@Value("#{jobParameters[season]}") String season){ PlayeRSStatsProcessor psp = new PlayeRSStatsProcessor(); psp.setStatisticType( StatisticType.valueOf(statType) ); psp.setSeason( season ); return psp; } @Bean @StepScope public ItemWriter<PlayeRSStats> writer(){ return new CustomWriter(); } @Bean public Job generateStatisticsJob() { return this.jobs.get("generateStatisticsJob") .incrementer(new RunIdIncrementer()) .start(processplayerStats()) //.end() .build(); } @Bean public Step processplayerStats() { return this.steps.get("processplayerStats") .<Player,PlayeRSStats> chunk(10) .reader(reader(null)) .processor(processor(null,null)) .writer(writer()) .build(); }
inputZipFile变量设置正确,文件存在于驱动器上.
我检查了FlatFileItemReader代码,并且ReaderNotOpenException发生在读者类的读者成员未设置时.读者成员设置为doOpen方法.
看起来doOpen不被调用.问题是为什么?
解决方法
今天关于Spring-Batch:如何从StepListener返回自定义Job退出代码和spring 返回文件的分享就到这里,希望大家有所收获,若想了解更多关于2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化、ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载、ElastciJobListener && AbstractDistributeOnceElasticJobListener、java – Spring Batch:org.springframework.batch.item.ReaderNotOpenException:读者必须先打开才能读取等相关知识,可以在本站进行查询。
本文标签: