将服务方法添加到队列以将其他数据加载到缓存

时间:2013-02-18 08:33:43

标签: java spring queue scheduling background-process

我有几个服务类(CustomerService,AgreementService)。使用ehcache缓存每个方法结果。

某些服务方法调用相当昂贵或需要很长时间才能运行。

当我加载时,例如客户我知道很有可能接下来需要客户协议。所以我需要将它们加载到后台缓存并使应用程序更负责任。

我尝试过使用方面。我已经将切入点设置为CustomerService.getById(id)方法和@AfterReturning建议。

@AfterReturning(
    pointcut = "execution(* com.example.CustomerService.getById(..))", 
    returning = "result"
)
public void loadCustomerAgreements(Object result) {
    Customer customer = (Customer) result;
    // calls method which caches result into ehcache
    agreementService.findByCustomer(customer.getId());
}

不幸的是,此解决方案立即加载客户及其协议(由于响应时间长,这是不可取的)。我想改为加载客户并返回给用户。然后异步加载协议。

为此目的,建议@After效果很好。但我无法获得客户身份证明,因此我不知道要加载哪些协议。

有没有办法如何使用方面或任何Spring触发器或其他技术来做到这一点?

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

我发现由方面运行的方法阻止了进一步的程序执行,因为它是在同一个线程中执行的。可能的解决方案是使用Spring Task Execution框架异步运行aspect方法。

Spring配置可能如下所示:

<task:annotation-driven executor="executorWithPoolSizeRange" scheduler="taskScheduler"/>
<task:executor id="executorWithPoolSizeRange" pool-size="5-25" queue-capacity="100"/>
<task:scheduler id="taskScheduler" pool-size="1"/>

然后方面看起来像:

@Async
@AfterReturning(
    pointcut = "execution(* com.example.CustomerService.getById(..))", 
    returning = "result"
)
public void loadCustomerAgreements(Object result) {
    Customer customer = (Customer) result;
    // calls method which caches result into ehcache
    agreementService.findByCustomer(customer.getId());
}

如果有可用的免费线程,这将在不同的线程中运行loadCustomerAgreements()方法。

有关详细信息,请参阅: