Spring的一些坑

1、使用注解注入外部值:

@Component
@PropertySource(value = {"classpath:spring-value.properties"})
public class AceMQProducer {
    public static final Logger LOGGER= LoggerFactory.getLogger(AceMQProducer.class);
    private DefaultMQProducer producer;
    @Value("${groupName}")
    private String groupName;
    @Value("${namesrvAddr}")
    private String namesrvAddr;
}

spring-value.properties:

groupName=AceProducerGroup
namesrvAddr=192.168.0.15:9876

2、在做Spring的UnitTest时,如果不使用SpringBoot:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class ProducerTest {
    @Autowired
    private AceMQProducer aceMQProducer;
    @Test
    public void testProducer() throws AceMQException{}
} 

spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.hxm.trade.common"/>
</beans>

切记加上<context:component-scan base-package="com.hxm.trade.common"/>,需要实例化的类要添加注解@Component。

如果使用SpringBoot,测试时就直接:

@RunWith(SpringRunner.class)
@SpringBootTest
public class InitDatabaseTest {
    @Autowired
    UserDAO userDAO;
}

3、bean实例化时执行的方法,用配置文件实现:

<bean id="" class="" init-method="init"></bean>

用注解实现:在初始化时需要执行的方法上加注解@PostConstruct

spring中Constructor、@Autowired、@PostConstruct的顺序:Constructor >> @Autowired >> @PostConstruct

关于@PostConstruct:

https://www.jianshu.com/p/98cf7d8b9ec3

4、FactoryBean

https://blog.youkuaiyun.com/w_linux/article/details/80063062

5、同一个接口下不同实例的注入:

https://blog.youkuaiyun.com/u010476994/article/details/80986435

转载于:https://my.oschina.net/u/2286010/blog/3032620

### Spring Batch 使用过程中的常见问题及解决方案 #### 1. **配置文件加载失败** 当使用 Spring Boot 配置 Spring Batch 应用程序时,可能会遇到无法正确加载配置文件的情况。这通常是因为 `application.properties` 或 `application.yml` 文件未被正确识别。 解决方法:确保在 `spring.batch.job.enabled=false` 的情况下手动触发 Job 执行[^4]。如果仍然存在问题,请验证配置文件路径是否正确以及是否存在拼写错误。 ```java @SpringBootApplication public class MyBatchApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(MyBatchApplication.class, args); // 手动启动 Job JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); Job job = (Job) context.getBean("myJob"); try { jobLauncher.run(job, new JobParameters()); } catch (Exception e) { e.printStackTrace(); } } } ``` --- #### 2. **Job 启动失败** 某些情况下,由于数据库连接池配置不当或事务管理器设置不正确,可能导致 Job 启动失败。 解决方法:确认使用的 DataSource 和 TransactionManager 是否已正确定义并注入到对应的 Bean 中[^5]。此外,检查数据库表结构是否与 Spring Batch 默认模式一致。 ```xml <!-- 数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> ``` --- #### 3. **ItemReader 报错** 在读取大量数据时,可能因内存不足或其他原因导致 ItemReader 出现异常。 解决方法:调整 Chunk Size 参数以减少每次处理的数据量[^3]。同时,考虑优化 SQL 查询语句以提高性能。 ```yaml spring: batch: chunk-size: 100 ``` --- #### 4. **Step 跳过机制失效** 有时即使设置了 Skip Policy,仍可能出现跳过的逻辑未能生效的现象。 解决方法:确保定义的 Skip Exception 类型匹配实际抛出的异常类,并合理配置最大跳过次数限制[^2]。 ```java @Bean public Step myStep() { return stepBuilder.get("myStep") .<String, String>chunk(10) .reader(itemReader()) .processor(itemProcessor()) .writer(itemWriter()) .faultTolerant() .skip(IllegalArgumentException.class) .skipLimit(10) .build(); } ``` --- #### 5. **多线程并发冲突** 启用多线程后,可能发生资源竞争或状态同步问题。 解决方法:引入 Thread-Safe 的组件设计,或者采用 Partitioner 来分配独立的任务给不同线程执行。 ```java @Bean public TaskExecutor taskExecutor() { SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor(); asyncTaskExecutor.setConcurrencyLimit(5); // 设置并发数 return asyncTaskExecutor; } @Bean public Step partitionedStep() { return stepBuilderFactory.get("partitionedStep") .partitioner(stepName(), partitioner()) .step(slaveStep()) .gridSize(gridSize()) // 定义分区数量 .taskExecutor(taskExecutor()) .build(); } ``` --- #### 6. **日志记录混乱** 随着批处理规模增大,日志输出变得难以追踪和分析。 解决方法:通过 Logback 或 Log4j 进行精细化的日志分类和级别控制[^1]。例如,为每个 Job 创建单独的日志文件以便于排查问题。 ```properties log4j.logger.org.springframework.batch=INFO log4j.appender.file.File=./logs/batch.log log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n ``` --- #### 7. **远程分片与分区差异理解不清** 开发者常混淆 Remote Chunks 和 Remote Partitions 的应用场景。 解释说明:Remote Chunks 主要适用于 Master 将任务切分为多个子任务发送至 Slave 节点完成;而 Remote Partitions 则侧重于按区域划分整个数据集再交由各节点分别计算。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值