为什么我会根据正确实现接口的bean从代理中获取强制转换错误?包和对象名称已更改,以保护专有数据。
我知道错误
java.lang.ClassCastException: com.sun.proxy.$Proxy20 cannot be cast to package.Order
当没有按预期实现接口时,通常会出现。在这种情况下,我正在实现促进代理生成的接口。
我的具体问题是在ItemWriter实现中的增强for循环中使用域对象的集合。这个异常是从下面增强的for循环I引用中抛出的。
public void write(List<? extends Order> items) throws Exception {
for ( Order order : items){
Order是OrderBean实现的接口。
public class OrderBean implements Order
并在Spring Java Configuration类中声明为BeanWrapperFieldSetMapper使用的Prototype。如下所示。
@Bean
@Scope("prototype")
public Order order()
作为一项实验,我注释掉了Java配置声明,并将其替换为下面的XML声明。
<bean name="order"
scope="prototype"
class="package.OrderBean"/>
我的整个配置显示在评论中请求的下方。我不确定为什么Order对象被代理,除非它可能来自BeanWrapperFieldSetMapper。
经过进一步测试,我发现我从任何具有Step范围的bean集中得到了相同的错误,就像在@Scope(“step”)中一样。
@Configuration
public class OrderProcessingBatchConfiguration {
@Value("${batch.jdbc.driver}")
private String driverClassName;
@Value("${batch.jdbc.url}")
private String driverUrl;
@Value("${batch.jdbc.user}")
private String driverUsername;
@Value("${batch.jdbc.password}")
private String driverPassword;
@Value("${order.delimiter}")
private String delimiter;
@Value("${order.item.field.names}")
private String[] orderItemFieldNames;
@Value("${order.item.file.path}")
private String orderItemFilePath;
@Value("${order.field.names}")
private String[] orderFieldNames;
@Value("${order.file.path}")
private String orderFilePath;
@Value("${query.order.clear}")
private String deleteOrderQuery;
@Value("${query.order.item.clear}")
private String deleteOrderItemQuery;
@Value("${ftp.host.name}")
private String ftpHostName;
@Value("${ftp.host.port}")
private Integer ftpHostPort;
@Value("${ftp.client.mode}")
private Integer ftpClientMode;
@Value("${ftp.file.type}")
private Integer ftpFileType;
@Value("${ftp.host.username}")
private String ftpUsername;
@Value("${ftp.host.password}")
private String ftpPassword;
@Value("${ftp.tasklet.retryIfNotFound}")
private Boolean retryIfNotFound;
@Value("${ftp.tasklet.download.attempts}")
private Integer downloadAttempts;
@Value("${ftp.tasklet.retry.interval}")
private Integer retryInterval;
@Value("${ftp.tasklet.file.name.pattern}")
private String fileNamePattern;
@Value("${ftp.host.remote.directory}")
private String remoteDirectory;
@Value("${ftp.client.local.directory}")
private File localDirectory;
@Value("${ftp.tasklet.sftp}")
private Boolean sftp;
@Value("${query.order.insert}")
private String orderInsertQuery;
@Value("${query.order.items.insert}")
private String orderItemInsertQuery;
@Autowired
@Qualifier("jobRepository")
private JobRepository jobRepository;
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(driverUrl);
dataSource.setUsername(driverUsername);
dataSource.setPassword(driverPassword);
return dataSource;
}
@Bean
public SimpleJobLauncher jobLauncher() {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
return jobLauncher;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
@Scope("prototype")
public OrderItem orderItem(){
return new OrderItemBean();
}
@Bean
@Scope("prototype")
public Order order(){
return new OrderBean();
}
@Bean
//@Scope("step")
public DelimitedLineTokenizer orderItemLineTokenizer(){
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(delimiter);
lineTokenizer.setNames(orderItemFieldNames);
return lineTokenizer;
}
@Bean
//@Scope("step")
public BeanWrapperFieldSetMapper<OrderItem> orderItemFieldSetMapper(){
BeanWrapperFieldSetMapper<OrderItem> orderItemFieldSetMapper = new BeanWrapperFieldSetMapper<OrderItem>();
orderItemFieldSetMapper.setPrototypeBeanName("orderItem");
return orderItemFieldSetMapper;
}
@Bean
//@Scope("step")
public DefaultLineMapper<OrderItem> orderItemLineMapper(){
DefaultLineMapper<OrderItem> orderItemLineMapper = new DefaultLineMapper<OrderItem>();
orderItemLineMapper.setLineTokenizer(orderItemLineTokenizer());
orderItemLineMapper.setFieldSetMapper(orderItemFieldSetMapper());
return orderItemLineMapper;
}
@Bean
//@Scope("step")
public Resource orderItemResource(){
Resource orderItemResource = new FileSystemResource(orderItemFilePath);
return orderItemResource;
}
@Bean
//@Scope("step")
public FlatFileItemReader<OrderItem> orderItemItemReader(){
FlatFileItemReader<OrderItem> orderItemItemReader = new FlatFileItemReader<OrderItem>();
orderItemItemReader.setLineMapper(orderItemLineMapper());
orderItemItemReader.setResource(orderItemResource());
return orderItemItemReader;
}
@Bean
//@Scope("step")
public DelimitedLineTokenizer orderLineTokenizer(){
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(delimiter);
lineTokenizer.setNames(orderFieldNames);
return lineTokenizer;
}
@Bean
//@Scope("step")
public BeanWrapperFieldSetMapper<Order> orderFieldSetMapper(){
BeanWrapperFieldSetMapper<Order> orderItemFieldSetMapper = new BeanWrapperFieldSetMapper<Order>();
orderItemFieldSetMapper.setPrototypeBeanName("order");
return orderItemFieldSetMapper;
}
@Bean
//@Scope("step")
public DefaultLineMapper<Order> orderLineMapper(){
DefaultLineMapper<Order> orderItemLineMapper = new DefaultLineMapper<Order>();
orderItemLineMapper.setLineTokenizer(orderLineTokenizer());
orderItemLineMapper.setFieldSetMapper(orderFieldSetMapper());
return orderItemLineMapper;
}
@Bean
//@Scope("step")
public Resource orderResource(){
Resource orderItemResource = new FileSystemResource(orderFilePath);
return orderItemResource;
}
@Bean
//@Scope("step")
public FlatFileItemReader<Order> orderItemReader(){
FlatFileItemReader<Order> orderItemItemReader = new FlatFileItemReader<Order>();
orderItemItemReader.setLineMapper(orderLineMapper());
orderItemItemReader.setResource(orderResource());
return orderItemItemReader;
}
@Bean
@Scope("step")
public Map<String, Order> orderCache(){
Map<String, Order> orderCache = new HashMap<String, Order>();
return orderCache;
}
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(dataSource());
}
@Bean
//@Scope("step")
public AggregatingFlatFileOrderItemReader aggregatingFlatFileOrderItemReader(){
AggregatingFlatFileOrderItemReader aggregatingFlatFileOrderItemReader = new AggregatingFlatFileOrderItemReader();
aggregatingFlatFileOrderItemReader.setJdbcTemplate(jdbcTemplate());
aggregatingFlatFileOrderItemReader.setOrderCache(orderCache());
aggregatingFlatFileOrderItemReader.setOrderItemFlatFileItemReader(orderItemItemReader());
aggregatingFlatFileOrderItemReader.setOrderFlatFileItemReader(orderItemReader());
aggregatingFlatFileOrderItemReader.setDeleteOrderQuery(deleteOrderQuery);
aggregatingFlatFileOrderItemReader.setDeleteOrderItemQuery(deleteOrderItemQuery);
return aggregatingFlatFileOrderItemReader;
}
@Bean
@Scope("step")
public SessionFactory ftpSessionFactory(){
DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();
ftpSessionFactory.setHost(ftpHostName);
ftpSessionFactory.setClientMode(ftpClientMode);
ftpSessionFactory.setFileType(ftpFileType);
ftpSessionFactory.setPort(ftpHostPort);
ftpSessionFactory.setUsername(ftpUsername);
ftpSessionFactory.setPassword(ftpPassword);
return ftpSessionFactory;
}
@Bean
@Scope(value="step")
public FtpGetRemoteFilesTasklet myFtpGetRemoteFilesTasklet(){
FtpGetRemoteFilesTasklet ftpTasklet = new FtpGetRemoteFilesTasklet();
ftpTasklet.setRetryIfNotFound(retryIfNotFound);
ftpTasklet.setDownloadFileAttempts(downloadAttempts);
ftpTasklet.setRetryIntervalMilliseconds(retryInterval);
ftpTasklet.setFileNamePattern(fileNamePattern);
ftpTasklet.setRemoteDirectory(remoteDirectory);
ftpTasklet.setLocalDirectory(localDirectory);
ftpTasklet.setSessionFactory(ftpSessionFactory());
ftpTasklet.setSftp(sftp);
return ftpTasklet;
}
@Bean
@Scope(value="step")
public OrderItemWriter orderItemWriter(){
OrderItemWriter orderItemWriter = new OrderItemWriter();
orderItemWriter.setJdbcTemplate(jdbcTemplate());
orderItemWriter.setOrderInsertQuery(orderInsertQuery);
orderItemWriter.setOrderItemInsertQuery(orderItemInsertQuery);
return orderItemWriter;
}