使用 spring aop 在DispatchAction中遇到的问题

 如果是通过反射技术调用的方法不能拦截到,否则就可以被拦截

@Aspect
@Component
public class Interceptor {
 @Pointcut("execution(org.apache.struts.action.ActionForward cn.itcast.web.action..*.*(org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionMapping,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse))")
 private void actionMethod(){
  
 }
 
 @Around("actionMethod()")
 public Object intercept(ProceedingJoinPoint pjp) throws Throwable {
  System.out.println("被拦截到的方法为:"+ pjp.getSignature().getName());
  return pjp.proceed();//执行被拦截的方法
 }
 
}

我们可以这样测试,有没有拦截到我们要执行的方法。
测试结果:execute方法可以被拦截,自定义方法无法拦截。如果继承的是action,可以被拦截到,如果继承的是dispatchAction,不能被拦截到
原因:简单说,如果是通过反射技术调用的方法不能拦截到,否则就可以被拦截。
那么为什么反射技术就不能被拦截到?
之所以我们在执行action执行,他能够被拦截,执行之前输出一句话,客户端从spring里面获得action bean是一个代理对象,代理对象中的方法内部呢:才会调用目标对象的方法,他会在执行代理对象之前呢,先执行输出方法,再执行目标方法,那么我们这样就在执行之前输出了这句话。
DispatchAction 继承 BaseAction ,BaseAction 继承 Action ,最终还是继承的Action,那么我们请求交给DispatchAction 执行时,他还是要执行execute方法,我们的DispatchAction对execute方法做了些手脚,重写了这个方法,他会获得配置文件里面的方法名称parameter,这个执行获取方法会通过反射技术获得method里面的方法。他里面没有接口,如果这个action没有接口,就会采用CGlib重写父类非final方法,

public class DepartmentManageAction extends DispatchAction {
 @Resource DepartmentService departmentService;
 
 /**
  * 部门添加界面
  */
 @Permission(module="department",privilege="insert")
 public ActionForward addDepartmentUI(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) throws Exception {
  DepartmentForm formbean = (DepartmentForm)form;
  return mapping.findForward("add");
 }
Public class Proxy98 extends DepartmentManageAction{
 Private Object target;//目标对象
 public ActionForward addDepartmentUI(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) throws Exception {
  他会调用我们定义的那个通知里面的环绕通知
  Return Interceptor。Intercept(pjp){
 System.out.println("被拦截到的方法为:"+ pjp.getSignature().getName());
  return pjp.proceed();//执行被拦截的方法
    判断后面还有没有要执行的切面,没有就会执行
Targer。EditDepartmentmentUi;
我们这样开来,他应该回输出啊,会执行我们定义的输出方法啊,但是你要记住我们无乱使用的是action还是DispatchAction都回先执行execute方法。Spring不会为代理对象重写的父类方法加入通知,他只会调用目标对象的execute方法。
}
 }

}

总结:为什么DispatchAction不可以
我们环绕通知切面编程原理,如果要拦截的对象没有实现接口,那么就会对他的内部方法也就目标对象生成代理对象(也就是加入通知),但是我们他不会对被拦截的类的父类方法加入通知,而我们的DispatchAction方法最终还是集成的Action方法,所以会先执行execute方法,execute方法所以不会加入通知,只会直接执行目标对象execute方法,而我们DispatchAction方法重写了execute方法,execute内部会通过invoke反射调用我们的目标方法,也就是上面的addDepartmentUI,我们目标对象addDepartmentUI方法内部本身并没有我们单独加上的处理(比如上面的输出),也就是说真实的执行过程,压根就没调用我们的代理对象,而是直接走的没有加入通知的execute方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值