service子类增加类拦截器后,父类拦截器就不执行了?

目的:让子类和父类的拦截器都执行。

现在有一个BaseService类,增加了如下拦截器:

  1. @Before({Base01Interceptor.class, Base02Interceptor.class, Base03Interceptor.class})
  2. public class BaseService {
  3.  
  4. }

然后其子类增加了如下拦截器:

  1. @Before(OtherInterceptor.class)
  2. public class IndexService extends BaseService {
  3.     public Ret testFunction(String key, String value) {
  4.         return Ret.create().set(key, value);
  5.     }
  6. }

然后在Controller里注入了:

  1. @Inject
  2. IndexService indexService;

现在是只能执行OtherInterceptor拦截器里的代码,父类里的三个拦截器代码都不执行。

如果把OtherInterceptor去掉,则父类的三个拦截器都会执行

如果把@Before(OtherInterceptor.class)放到子类的的方法前面,类似如下:


  1. public class IndexService extends BaseService {
  2.     @Before(OtherInterceptor.class)
  3.     public Ret testFunction(String key, String value) {
  4.         return Ret.create().set(key, value);
  5.     }
  6. }

则上述四个拦截器都会被执行。


经过波总和杜总的帮助,是说java自身的问题。我经过摸索发现通过如下方法可以那到子类和父类上的拦截器:

  1. @Before(OtherInterceptor.class)
  2. public class IndexService extends BaseService {
  3.     public Ret testFunction(String key, String value) {
  4.         Before before1 = IndexService.class.getAnnotation(Before.class);
  5.         //这里可以递归直到getSuperclass()返回的是Object,我这里只是测试拿父类。
  6.         Before before2 = IndexService.class.getSuperclass().getAnnotation(Before.class);
  7.         //
  8.         Class<? extends Interceptor>[] classList = before1.value();
  9.         Ret ret = Ret.create();
  10.         int i=1;
  11.         for(Class<? extends Interceptor> clazz : classList) {
  12.             ret.put("IndexService"+(i++), clazz.getName());
  13.         }
  14.         //
  15.         i=1;
  16.         classList = before2.value();
  17.         for(Class<? extends Interceptor> clazz : classList) {
  18.             ret.put("BaseService"+(i++), clazz.getName());
  19.         }
  20.         return ret;
  21.     }
  22. }

@JFinal @杜福忠

有没有可能在jfinal内做一下改进?

评论区

杜福忠

2022-09-24 17:14

https://jfinal.com/doc/4-5
以上的 me.setInjectDependency(true) 仅是针于 jfinal 的 web 组件而言的配置。而 Aop.get(...)、Aop.inject(...) 无需配置即可支持注入。

zzutligang

2022-09-24 17:25

@杜福忠 我知道me.setInjectDependency(true)这个作用。Aop.get增强我也知道用处。现在是service子类增加class级拦截器后,父类里就不执行了。但去掉子类拦截器,父类拦截器就执行了。

杜福忠

2022-09-24 18:34

@zzutligang 一个注解类确实不支持 子类 和父类 同时声明,拿不到注解对象了

JFinal

2022-09-24 21:51

这是 java 语法决定的,子类可以继承父类声明的注解,前提是你在子类中没有覆盖掉它

zzutligang

2022-09-25 15:35

@JFinal @杜福忠 有没有可能在遍历拦截器的时候,通过class的getSuperClass()方法遍历出来所有父类,然后拿到父类的拦截器呢?

zzutligang

2022-09-25 15:55

@JFinal @杜福忠 我做了一个实验,确实可以通过getSuperClass拿到父类的Before注解。可以看正文的最下面我实验的代码。有没有可能在Jfinal内部做个改进。或则自己扩展一下?

JFinal

2022-09-25 20:04

@zzutligang 对每个方法都去父类拿它的注解,而父类还有可能有父类,代价太大

而这个需求几乎无人提及

你在子类中不使用 @Before 覆盖父类的是自动拿到的,使用 @Before 以后要注意将父类的拦截器一并放在当前方法

zzutligang

2022-09-26 10:41

@JFinal 我觉着个问题很重要,并且,一般这种继承不会有太多层,3层4层顶天了。系统开销也不会增加多少的。能不能提供一个全局开关,是否启用遍历父类的拦截器。默认是关闭状态。我相信也会有其他人需要这个功能。我现在暂时就是子类增加@Before的时候,把父类里的@Before复制过来,但总觉得这不是解决问题的办法。也脱离了JFinal优雅的设计初衷。

zeroabc

2022-09-26 11:43

长期都是这样的,突然改成支持获取父类的注解可能引发更大的问题

热门反馈

扫码入社