开发者社区> 问答> 正文

AOP切入elasticsearch 的 Java API RestHighLe?400报错

最近打算在现有的系统基础上,基于用户的权限做数据的过滤。但是考虑的现有系统已经有一定的规模,所以决定在数据源客户端层面用aop 在查询前切入,修改查询的条件,达到数据权限过滤的效果,且这样考虑影响的代码较少。但是在aop切入的过程中遇到了莫名奇妙的问题,一直切入不成功,且不报错。下面对这个过程进行记录。

AOP配置切入 RestHighLevelClient.search()

EsClientSearchAspect.java

@Aspect@Componentpublic EsClientSearchAspect {

    /**
     * 切入点
     */
    @Pointcut("execution(* org.elasticsearch.client.RestHighLevelClient.search(..))")  
    public void pointCut(String param) {
    } 
    
    /**
     * 在执行前做一些事
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("执行前")
    }
}

但是debugger 时发现 doBefore 并未执行,所有我怀疑是aop配置的问题,所以,我将切入点表达式换为业务代码,但是当业务代码执行前却aop生效了。所以我怀疑RestHighLevelClient 对象 并没有真正的交给spring容器管理。因为没加入spring容器的对象,spring是没发AOP的。但是不管为什么,问题总的解决,aop不行就采用另外一种方法,在查询之前修改查询条件就行。

AOP失败的另一种尝试,Wapper模式

既然aop不行,那我新建一个 RestHighLevelClient 的 Wapper类,再重写 search方法,并在 父类的search 之前做点事就行了。于是乎,我创建了RestHighLevelClientWapper类继承RestHighLevelClient,重写 search 方法,但是我发现重写的时候,IDE 报错了,说不能重写,于是我看了 RestHighLevelClient 的源码,部分源码如下:

public class RestHighLevelClient implements Closeable {
    ……

    public final SearchResponse search(SearchRequest searchRequest, Header... headers) throws IOException {
        ……
    }
    ……
}

什么!!! search 是final 不能重写,那岂不是没办法了吗??等等,AOP 失败 ,search 不能重写……,好像有什么关联。spring AOP 是通过cglib 代理来实现的,cglib是通过类继承来实现的,既然 search 不能重写 那么 cglib 代理肯定回失败!!我的天啊!

再回顾JDK 代理和 cglib代理

jdk代理 是通过接口的方式实现代理

cglib代理 是通过改变字节码通过 继承的方式来实现的

关于数据过滤陷入沉思

看来cglib代理也有不足的地方,但是jdk代理必须的有相应的接口。这个问题既不能通过动态代理,也不能通过Wapper模式来处理,那该如何是好呀?看来只能写公用业务,尽量最少的侵入代码了。或者各位网友有什么良策?

展开
收起
爱吃鱼的程序员 2020-06-06 09:18:27 651 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <p>暴力方案:下载源码->为所欲为->打包</p>
                    
    
                            你确定不是:下载源码->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->为所欲为->跑路?
                        
    
                        <p>可以写个公共类封装下,只需要对公共类拦截</p>
                    
    
                            也只能如此了
    
    2020-06-06 09:18:38
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载