在 Spring Boot 中,@PostConstruct 注解用于标记一个方法,在 Bean 初始化完成后执行。如果使用 @PostConstruct 注解的方法依赖于其他 Bean,那么这些 Bean 必须在该方法执行之前初始化完成。
如果在 @PostConstruct 方法中调用 MyBatis 的 Mapper 接口,可能会出现 Mapper 加载失败的问题。这是因为 MyBatis 的 Mapper 接口需要在 Spring 容器启动时被扫描并加载,而 @PostConstruct 方法执行的时间点比较靠后,可能导致 Mapper 接口还未被加载就被调用了。
解决这个问题的方法有两种:
1. 将 Mapper 接口的扫描放到较早的阶段
可以通过在启动类上添加 @MapperScan 注解来指定 Mapper 接口的扫描路径,并将其放到较早的阶段,确保 Mapper 接口在 @PostConstruct 方法执行之前已经被扫描并加载。
例如:
```java
@SpringBootApplication
@MapperScan("com.example.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
```
2. 使用延迟加载的方式调用 Mapper 接口
可以使用 Spring 提供的 @Autowired 注解将 Mapper 接口注入到 @PostConstruct 方法中,并使用延迟加载的方式调用 Mapper 接口。
例如:
```java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@PostConstruct
public void init() {
// 使用延迟加载的方式调用 Mapper 接口
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
userMapper.selectByPrimaryKey(1);
}
});
}
// 省略其他方法
}
```
上面的代码中,使用 @Autowired 注解将 UserMapper 接口注入到 UserServiceImpl 类中,在 @PostConstruct 方法中使用延迟加载的方式调用了