service层方法无法使用@Before(CacheInterceptor.class)

有一个首页接口,会将若干个service的方法,而后一起返回,但是其中两个service的方法对时效性要求比较低,可以用缓存,所以在service的方法上加上@Before(CacheInterceptor.class)

Service如下:

public class WorkService{
    public final static WorkService me = Enhancer.enhance(WorkService.class);
    
    @Before({ CacheInterceptor.class })
    public Map<String, Object> getRecommendAudio(int pageNum, int pageSize) {
        ...代码
    }
}

在Controller中调用这个方法就出错了,原因如下:

CacheInterceptor中有如下代码:

CacheInterceptor

final public void interceptor(Invocation inv){
    Controller controller = inv.getController();
    ...
}

但是inv.getController()如下:

public Controller getController() {
   if (action == null)
      throw new RuntimeException("This method can only be used for action interception");
   return (Controller)target;
}

必须Action不为null,才可以返回

而刚好使用Enhancer.enhance(WorkService.class)增强过后的WorkService调用方法时如下:

public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy){
    ...
    Invocation invocation = new Invocation(target, method, args, methodProxy, finalInters);
    ...
}

生成的Invocation刚好action=null;

public Invocation(Object target, Method method, Object[] args, MethodProxy methodProxy, Interceptor[] inters) {
   this.action = null;
   this.target = target;
   this.method = method;
   this.args = args;
   this.methodProxy = methodProxy;
   this.inters = inters;
}


我感觉,inv.getController()的action必须不为null的判断,就是针对service的增强方法而增加的,但是为什么要避免在service的增强方法中使用inv.getController()呢?


这种使用方式有什么弊端呢?

JFinal版本:jfinal-java8 3.2

评论区

JFinal

2017-10-26 16:17

Invocation 这个类,可以在 controller 层与 service 层的 aop 中通用,但是这两层之上又有所不同,例如 service 层就没有 action 这种东东,所以要做个判断

pfjia

2017-10-26 16:38

@JFinal 哦,如果是在service对方法做增强,生成的Invocation中target是一个代理对象,并不是Controller,调用inv.getController()时即使不做判断也会出现类型转换异常

如果要在service做缓存可以仿照CacheInterceptor写一个ServiceCacheInterceptor,其中不使用Controller和Action即可
多谢波总!!!

热门反馈

扫码入社