我有一个包含BookMapper bean的spring引导项目:
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BookMapper {
// some CRUD methods here...
}bean是由mybatis创建的,它是一个Singleton。通常,我在@Autowired中使用bean
@Service
public BookService {
@Autowired
private BookMapper bookMapper;
}我也有这样的文件:
@Component
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext ac;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ac = applicationContext;
}
public static <T> T getBean(Class<T> clazz){
return ac.getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz){
return ac.getBean(name, clazz);
}
}有时,我只需使用BeanUtil类获取bean:
BookMapper bookMapper = BeanUtil.getBean(BookMapper.class);这很方便,因为我可以从静态方法中获得一个bean。
现在的问题是,当我运行集成测试时,我发现使用上述两种方法(@Autowired和BeanUtil)获取的@Autowired有时是不同的(而且有时是相同的,我无法重现问题)。为什么?这不应该发生,因为BookMapper是一个Singleton。可能有什么原因吗?
发布于 2022-04-27 13:34:06
我也有类似的问题。
在我的例子中,由于两个测试有不同的配置(不同的配置文件,或者使用模拟覆盖bean ),所以在运行所有集成测试时,会多次启动spring上下文。
在static ApplicationContext ac中有BeanUtil,所以spring可以在创建新上下文的过程中创建不同的BeanUtil,但是它们将ApplicationContext存储在static中,因此这些上下文之间可能存在一些广泛的交互
发布于 2022-04-30 05:29:55
经过长时间的调试,我发现了原因。我在测试中使用@MockBean。在本例中,spring-test将创建第二个ApplicationContext,这与BeanUtil在我的问题代码中使用的ApplicationContext不同。当您有两个上下文时,每个类将有两个bean。
我不是@MockBean的大量用户,所以我现在只删除它,然后问题就消失了。
https://stackoverflow.com/questions/72027287
复制相似问题