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

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

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

@Before({Base01Interceptor.class, Base02Interceptor.class, Base03Interceptor.class})
public class BaseService {

}

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

@Before(OtherInterceptor.class)
public class IndexService extends BaseService {
    public Ret testFunction(String key, String value) {
        return Ret.create().set(key, value);
    }
}

然后在Controller里注入了:

@Inject
IndexService indexService;

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

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

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


public class IndexService extends BaseService {
    @Before(OtherInterceptor.class)
    public Ret testFunction(String key, String value) {
        return Ret.create().set(key, value);
    }
}

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


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

@Before(OtherInterceptor.class)
public class IndexService extends BaseService {
    public Ret testFunction(String key, String value) {
        Before before1 = IndexService.class.getAnnotation(Before.class);
        //这里可以递归直到getSuperclass()返回的是Object,我这里只是测试拿父类。
        Before before2 = IndexService.class.getSuperclass().getAnnotation(Before.class);
        //
        Class<? extends Interceptor>[] classList = before1.value();
        Ret ret = Ret.create();
        int i=1;
        for(Class<? extends Interceptor> clazz : classList) {
            ret.put("IndexService"+(i++), clazz.getName());
        }
        //
        i=1;
        classList = before2.value();
        for(Class<? extends Interceptor> clazz : classList) {
            ret.put("BaseService"+(i++), clazz.getName());
        }
        return ret;
    }
}

@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

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

热门反馈

扫码入社