gpt4 book ai didi

java - Spring Batch 通过扩展 JdbcCursorItemReader 创建自定义阅读器

转载 作者:行者123 更新时间:2023-12-02 06:11:59 26 4
gpt4 key购买 nike

我需要通过扩展 JdbcCursorItemReader 来制作自定义阅读器。我这样做如下:

package sample.peektry;

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("myReader")
public class MyReader implements ItemReader<MyBean> {

@Autowired
MyPeekableReader myPeekableReader;

public MyPeekableReader getMyPeekableReader() {
return myPeekableReader;
}

public void setMyPeekableReader(MyPeekableReader myPeekableReader) {
this.myPeekableReader = myPeekableReader;
}

@Override
public MyBean read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
System.out.println(" I will peek and read... :)");
return null;
}

}

package sample.peektry;

import org.springframework.batch.item.support.SingleItemPeekableItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("myPeekableReader")
public class MyPeekableReader extends SingleItemPeekableItemReader<MyBean> {

@Autowired
private MyJdbcReader myJdbcReader;

public MyJdbcReader getMyJdbcReader() {
return myJdbcReader;
}

public void setMyJdbcReader(MyJdbcReader myJdbcReader) {
this.myJdbcReader = myJdbcReader;
}


}

此外,MyRowMapper 实现了 RowMapper 并具有 @Component("myRowMapper")。类似地,MyPrepStmntSetter 实现了PreparedStatementSetter 并具有@Component("myPrepStmntSetter")

package sample.peektry;

import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("myJdbcReader")
public class MyJdbcReader extends JdbcCursorItemReader<MyBean> {

@Resource
DataSource dataSource;

@Autowired
MyRowMapper myRowMapper;

@Autowired
MyPrepSetter myPrepSetter;

public DataSource getDataSource() {
return dataSource;
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

public MyRowMapper getMyRowMapper() {
return myRowMapper;
}

public void setMyRowMapper(MyRowMapper myRowMapper) {
this.myRowMapper = myRowMapper;
}

public MyPrepSetter getMyPrepSetter() {
return myPrepSetter;
}

public void setMyPrepSetter(MyPrepSetter myPrepSetter) {
this.myPrepSetter = myPrepSetter;
}




}

配置:

  1. 在batch-infra.xml中:

    <batch:job-repository id="jobRepository" data-source="dataSource"
    transaction-manager="transactionManager" />

    <!-- connect to database -->
    <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver" />
    <property name="url" value="jdbc:derby://localhost:1527/MyDB" />

    <bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository"></property>

    <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>

  2. batch-jobs.xml:

    <import resource="classpath:/META-INF/spring/batch/jobs/myJob.xml" />
  3. 在 app-context.xml 中(在 xmlns 和所有之后):

    <context:component-scan base-package="sample.peektry" />

    <import resource="classpath:/META-INF/spring/batch/batch-infra.xml" />

    <import resource="classpath:/META-INF/spring/batch/batch-jobs.xml" />

上述配置对于除 dataSource 之外的所有属性都运行良好。 IE。运行时,我得到:IllegalArgumentException DataSource必须提供

堆栈跟踪:

2014-02-16 14:56:07,195 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c7e553: startup date [Sun Feb 16 14:56:07 IST 2014]; root of context hierarchy>
2014-02-16 14:56:07,291 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/app-context.xml]>
2014-02-16 14:56:07,625 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/batch/batch-infra.xml]>
2014-02-16 14:56:10,210 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/batch/batch-jobs.xml]>
2014-02-16 14:56:12,766 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/batch/jobs/myJob.xml]>
2014-02-16 14:56:12,872 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'myJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]>
2014-02-16 14:56:13,115 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d332b: defining beans [myJdbcReader,myPeekableReader,myPrepSetter,myReader,myRowMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,dataSource,jobLauncher,transactionManager,step1,myJob]; root of factory hierarchy>
2014-02-16 14:56:13,215 INFO [org.springframework.jdbc.datasource.DriverManagerDataSource] - <Loaded JDBC driver: org.apache.derby.jdbc.ClientDriver>
2014-02-16 14:56:13,304 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d332b: defining beans [myJdbcReader,myPeekableReader,myPrepSetter,myReader,myRowMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,dataSource,jobLauncher,transactionManager,step1,myJob]; root of factory hierarchy>
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myJdbcReader' defined in file [C:\Users\user\Documents\workspace-sts-3.3.0.RELEASE\sb-listener-test\target\classes\sample\peektry\MyJdbcReader.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: DataSource must be provided
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at sample.peektry.MyMain.main(MyMain.java:16)
Caused by: java.lang.IllegalArgumentException: DataSource must be provided
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.batch.item.database.AbstractCursorItemReader.afterPropertiesSet(AbstractCursorItemReader.java:150)
at org.springframework.batch.item.database.JdbcCursorItemReader.afterPropertiesSet(JdbcCursorItemReader.java:107)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 12 more

我哪里出错了?是否是由于混合了 XML 配置和组件扫描?

最佳答案

问题出在 MyJdbcReader 类中的 dataSource 字段。实际上,您并没有重写父类(super class)的 dataSource 字段,只是因为它是私有(private)的(在父类(super class)中)。请参阅source code on grepcode .

您所做的是声明一个新的包私有(private)字段,该字段绝不连接到父类(super class)中的 dataSource 字段。有关更多详细信息,请参阅 Java 中的继承原则。

通过查看源代码(在上面的超链接中提到),您可以在第 150 行看到需要设置 dataSource 字段。但就你而言,事实并非如此!只是因为您将 DataSource 连接到与父类(super class)中的 dataSource 无关的字段。

我建议您重写 setter 方法(这是公共(public)的)并将注释移至 setter。像这样的事情:

删除这些行:

@Resource
DataSource dataSource;

并更改 setDataSource 定义,如下所示:

@Override
@Resource
public void setDataSource(DataSource dataSource){
super.setDataSource(dataSource);
}

并删除getDataSource 定义。它将失败,因为作用域中不再有 dataSource 变量。

关于java - Spring Batch 通过扩展 JdbcCursorItemReader 创建自定义阅读器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21802440/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com