我在一个类中有一个@Cacheable方法。我尝试在第一次调用该方法后创建缓存,然后,第二次调用不应该进入方法getCacheLeads。
@Service
public class LeadService {
@Autowired
private LeadRepository leadRepository;
@Autowired
public LeadService(LeadRepository leadRepository) {
this.leadRepository = leadRepository;
}
public void calculateLead(Lead leadBean) {
Lead lead = this.getCacheLeads(leadBean);
}
@Cacheable(cacheNames="leads", key="#leadBean.leadId")
public Lead getCacheLeads(Lead leadBean){
Lead result = leadRepository.findByLeadId(leadBean.getLeadId());
***logic to transform de Lead object***
return result;
}
}
但在测试期间,该缓存从未被使用,使用相同的参数(serviceIsCalled)调用它两次,以确保它被调用两次来检查它。
@ExtendWith(SpringExtension.class)
public class LeadServiceTest {
private LeadService leadService;
@Mock
private LeadRepository leadRepository;
@Autowired
CacheManager cacheManager;
@BeforeEach
public void setUp(){
leadService = new LeadService(leadRepository);
}
@Configuration
@EnableCaching
static class Config {
@Bean
CacheManager cacheManager() {
return new ConcurrentMapCacheManager("leads");
}
}
@Test
public void testLead(){
givenData();
serviceIsCalled();
serviceIsCalled();
checkDataArray();
}
private void givenData() {
Lead lead = new Lead();
lead.setLeadId("DC635EA19A39EA128764BB99052E5D1A9A");
Mockito.when(leadRepository.findByLeadId(any()))
.thenReturn(lead);
}
private void serviceIsCalled(){
Lead lead = new Lead();
lead.setLeadId("DC635EA19A39EA128764BB99052E5D1A9A");
leadService.calculateLead(lead);
}
private void checkDataArray(){
verify(leadRepository, times(1)).findByLeadId(anyString());
}
}
为什么叫了两次?
1条答案
按热度按时间tjvv9vkg1#
你在这里有很多事情要做,有人看着这个,回答你的问题,肯定会读到字里行间的意思。
首先,您的Spring配置甚至不正确,您正在使用
ConcurrentMapCacheManager
构造函数“静态”声明Spring应用程序(和测试)使用的所有缓存的名称,该构造函数接受缓存名称数组作为参数。注意:由名称明确标识的高速缓存,并且只有这些高速缓存在运行时可用。
在这种情况下,您的唯一缓存称为“LEAD_DATA”。
注意:只有'ConcurrentMapCacheManager中的no arg构造函数允许在运行时按名称动态创建缓存。
但是,在您的
@Service
LeadService
类@Cacheable
getCacheLeads(:Lead)
方法中,您声明了要用作“leads”的缓存。这种配置缺失实际上会在运行时导致类似于以下内容的异常:
此外,我没有看到
LeadsService
bean“外部”调用@Cacheable
、getCacheLeads(..)
方法的任何内容。具体如下:
如果
calculateLead(:Lead)
LeadService
方法正在调用@Cacheable
,getCacheLeads(:Lead)
LeadService
方法(内部),那么这将不会导致缓存功能启动,因为您已经“落后于”Spring设置的AOP代理,以便为您的LeadService
bean“启用”缓存行为。请参见Spring框架AOP文档中有关这方面的内容。
注意:Spring的Cache Abstraction,就像Spring的Transaction Management一样,是建立在Spring AOP基础结构之上的,Spring中的许多其他东西也是如此。
在您的情况下,这意味着:
但是,在
LeadSevice.calculateLead(:Lead)
和LeadService.getCacheLeads(:Lead)
之间,不涉及PROXY,因此不会应用Spring的缓存行为。只是......
将导致AOP代理使用被调用的缓存拦截器进行修饰,并应用缓存行为。
您可以看到,如果按照我的example test class(根据您的域建模)中所演示的那样正确配置和使用,您的用例将正常工作。
查找说明您的配置在您的情况下失败的原因的注解。