gpt4 book ai didi

java - 如何在Spring Boot aop @Around函数中创建事务?

转载 作者:行者123 更新时间:2023-12-02 10:21:30 26 4
gpt4 key购买 nike

我想使用 Spring Boot AOP 实现一种授权方法。最初的想法是,如果从 REST 调用返回的返回对象没有通过授权检查,则会抛出未经授权的异常。

我这样做:

@Aspect
@Component
public class AuthAspect {
@Around("AllRestExecPoint()")
public Object auth(ProceedingJoinPoint point) throws Throwable {
Object returnObject = point.proceed();
if (!checkAuthorization(returnObject)) {
throw new UnauthException();
}
return returnObject;
}
}

但是,问题是,如果此 REST 服务将对我的数据库执行某些 INSERT 或 UPDATE,它将在我的授权检查之前提交。因此,将抛出UnauthException,但事务仍会提交。

第一次尝试我想在 proceed() 调用之前手动创建事务并在返回之前提交它,但失败了。

@Aspect
@Component
public class AuthAspect {
private final EntityManager em;

@Autowired
public AuthAspect(EntityManager em) {
this.em = em;
}

@Around("AllRestExecPoint()")
public Object auth(ProceedingJoinPoint point) throws Throwable {
em.getTransaction().begin();

Object returnObject = point.proceed();
if (!checkAuthorization(returnObject)) {
throw new UnauthException();
}

em.getTransaction().commit();

return returnObject;
}
}

这将导致java.lang.IllegalStateException:不允许在共享EntityManager上创建事务 - 请改用Spring事务或EJB CMT

我在网上搜索了一些答案,需要修改web.xml文件,但我不想使用xml来进行配置。

最佳答案

从你的标签来看,你正在使用 Spring Boot。 Spring Boot 提供了预配置的TransactionTemplate如果您想手动控制事务,可以使用它。

而不是 EntityManger 将其注入(inject)到您的方面并将您的代码包装在其中。

@Aspect
@Component
public class AuthAspect {
private final TransactionTemplate tx;

public AuthAspect(TransactionTemplate tx) {
this.tx = tx;
}

@Around("AllRestExecPoint()")
public Object auth(ProceedingJoinPoint pjp) throws Throwable {

return tx.execute(ts -> this.executeAuth(pjp));
}

private Object executeAuth(ProceedingJoinPoint pjp) {
Object returnObject;
try {
returnObject = pjp.proceed();
} catch (Throwable t) {
throw new AopInvocationException(t.getMessage(), t);
}
if (!checkAuthorization(returnObject)) {
throw new UnauthException();
}
return returnObject;
}
}

这将执行事务内的逻辑。我将实际逻辑移至一个方法,以便 lambda 可以是单个方法而不是代码块。 (个人偏好/最佳实践)。

关于java - 如何在Spring Boot aop @Around函数中创建事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54320758/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com