如何给Spring MVC的action加上事务

如何给Spring MVC的action加上事务,第1张

其实就是一个加载顺序的问题

首先使用了spring

MVC的项目是不需要配置action bean,而是通过spring

mvc的配置文件进行扫描注解加载的,spring事务配置文件还有上下文都是通过org.springframework.web.context.ContextLoaderListener加载的,而spring

MVC的action是通过org.springframework.web.servlet.DispatcherServlet加载的,这样就有个优先级的问题了,web是先启动ContextLoaderListener后启动DispatcherServlet,在ContextLoaderListener加载的时候action并没在容器中,所以现在使用AOP添加事务或者扫描注解都是无用的。

那么解决办法就是在DispatcherServlet加载的spring-MVC配置文件后再加上AOP事务扫描配置就OK了

1

2

3

4

5

6

7

8

<tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="questionReply" propagation="REQUIRED"/>

</tx:attributes>

</tx:advice>

<aop:config>

<aop:advisor advice-ref="defaultTxAdvice" pointcut="execution(* com.jeecms.cms.action.front.PhQuestionAct.*(..))"/>

</aop:config>

Object result = pjp.proceed()没有将参数传入

应该为

//获得method方法的参数

Object[] args = point.getArgs()

Object result = pjp.proceed(args)

Interceptor 可以对方法进行拦截,并提供机会在方法的前后添加切面代码,实现 AOP 的核心目标。Interceptor 接口仅仅定义了一个方法 public void intercept(Invocation inv)。以下是简单示例:

public class DemoInterceptor implements Interceptor {

    public void intercept(Invocation inv) {

       //文件记录或者数据库记录

       LogKit.info("系统日志记录开始")

       

       inv.invoke()

       //

       LogKit.info("系统日志记录结束")

    }

}

以上代码中的 DemoInterceptor 将拦截目标方法,并且在目标方法调用前后向控制台输出文本。inv.invoke() 这一行代码是对目标方法的调用,在这一行代码的前后插入切面代码可以很方便地实现AOP。

注意:必须调用 inv.invoke() 方法,才能将当前调用传递到后续的 Interceptor 与 Action。

网页链接

JFinal中的AOP被划分为控制层AOP以及业务层AOP,严格来说业务层AOP并非仅限于在业务层使用,因为JFinal AOP可以应用于其它任何地方。

控制层拦截器的触发,只需发起action请求即可。业务层拦截器的触发需要先使用enhance方法对目标对象进行增强,然后调用目标方法即可。以下是业务层AOP使用的例子:

// 定义需要使用AOP的业务层类

public class OrderService {

    // 配置事务拦截器

    @Before(Tx.class)

    public void payment(int orderId, int userId) {

       // service code here

    }

}

 

// 定义控制器,控制器提供了enhance系列方法可对目标进行AOP增强

public class OrderController extends Controller {

    public void payment() {

       // 使用 enhance方法对业务层进行增强,使其具有AOP能力

       OrderService service = enhance(OrderService.class)

       

       // 调用payment方法时将会触发拦截器

       service.payment(getParaToInt("orderId"), getParaToInt("userId"))

    }

}

以上代码中OrderService是业务层类,其中的payment方法之上配置了Tx事务拦截器,OrderController是控制器,在其中使用了enhance方法对OrderSevice进行了增强,随后调用其payment方法便可触发Tx拦截器。简言之,业务层AOP的触发相对于控制层仅需多调用一次enhance方法即可,而Interceptor、Before、Clear的使用方法完全一样。网页链接


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/7942542.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存