|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
AOP的一个例子
既然你已经了解了所有组成部分的工作原理,我们可以将它们整合起来来实现 有用的东西。
业务服务的执行有时可能因并发问题而失败(对于
例如,僵局失败者)。如果重试该行动,成功的可能性很大
下次再试。对于适合重新尝试的商业服务
条件(幂冪级作,无需返回用户进行冲突
我们希望透明地重试作,以避免客户端看到PessimisticLockingFailureException.这是一项明确跨越界限的要求
服务层中的多个服务,因此非常适合通过
方面。
因为我们想重试作,需要参考相关建议以便
叫进行多次。以下列表展示了基本的方面实现:
-
Java
-
Kotlin
@Aspect
public class ConcurrentOperationExecutor implements Ordered {
private static final int DEFAULT_MAX_RETRIES = 2;
private int maxRetries = DEFAULT_MAX_RETRIES;
private int order = 1;
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
@Around("com.xyz.CommonPointcuts.businessService()") (1)
public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
int numAttempts = 0;
PessimisticLockingFailureException lockFailureException;
do {
numAttempts++;
try {
return pjp.proceed();
}
catch(PessimisticLockingFailureException ex) {
lockFailureException = ex;
}
} while(numAttempts <= this.maxRetries);
throw lockFailureException;
}
}
| 1 | 参考文献商务服务命名点切口定义于“共享命名点切定义”。 |
@Aspect
class ConcurrentOperationExecutor : Ordered {
private val DEFAULT_MAX_RETRIES = 2
private var maxRetries = DEFAULT_MAX_RETRIES
private var order = 1
fun setMaxRetries(maxRetries: Int) {
this.maxRetries = maxRetries
}
override fun getOrder(): Int {
return this.order
}
fun setOrder(order: Int) {
this.order = order
}
@Around("com.xyz.CommonPointcuts.businessService()") (1)
fun doConcurrentOperation(pjp: ProceedingJoinPoint): Any? {
var numAttempts = 0
var lockFailureException: PessimisticLockingFailureException
do {
numAttempts++
try {
return pjp.proceed()
} catch (ex: PessimisticLockingFailureException) {
lockFailureException = ex
}
} while (numAttempts <= this.maxRetries)
throw lockFailureException
}
}
| 1 | 参考文献商务服务命名点切口定义于“共享命名点切定义”。 |
注意,该切面实现了命令接口,这样我们就可以设置 的优先级
比交易建议更高的方面(我们希望每次都获得新的交易)
重试)。这maxRetries和次序这两个属性都由 Spring 配置。这
主要作用发生在doConcurrentOperation关于建议。注意,对于
我们对每个人应用重试逻辑商务服务.我们试图继续前行,
如果我们用 a 失败PessimisticLockingFailureException,我们再试一次,除非
我们已经用尽了所有重试尝试。
对应的Spring配置如下:
<aop:aspectj-autoproxy/>
<bean id="concurrentOperationExecutor"
class="com.xyz.service.impl.ConcurrentOperationExecutor">
<property name="maxRetries" value="3"/>
<property name="order" value="100"/>
</bean>
为了精炼体,使其只重试幂零运算,我们可以定义如下幂等注解:
-
Java
-
Kotlin
@Retention(RetentionPolicy.RUNTIME)
// marker annotation
public @interface Idempotent {
}
@Retention(AnnotationRetention.RUNTIME)
// marker annotation
annotation class Idempotent
然后我们可以用注释来注释服务作的实现。变革
对于只重试幂零元作的方面,需要细化点割
表达式仅使得@Idempotent作匹配如下:
-
Java
-
Kotlin
@Around("execution(* com.xyz..service.*.*(..)) && " +
"@annotation(com.xyz.service.Idempotent)")
public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
// ...
}
@Around("execution(* com.xyz..service.*.*(..)) && " +
"@annotation(com.xyz.service.Idempotent)")
fun doConcurrentOperation(pjp: ProceedingJoinPoint): Any? {
// ...
}