Impala JDBC 动态设置查询选项

本文介绍了如何利用AspectJ动态设置Impala JDBC查询选项,详细讲解了AOP概念,比较了Spring AOP和AspectJ的区别,并提供了实现步骤,包括定义切面类、添加aspects编译插件和测试验证。
摘要由CSDN通过智能技术生成

前篇文章 Impala 设置查询选项 介绍常用设置查询选项的方法,本文介绍实现动态设置查询选项用到的技术和过程。

AOP 概念

在我们开始之前,让我们对术语和核心概念做一个回顾:

  • Aspect:切面,由切点和增强相结合而成,定义增强应用到哪些切点上。即一个横跨多个核心逻辑的功能,或者称之为系统关注点。
  • Joinpoint:连接点,这是程序执行过程中的一个特殊点,例如方法执行,构造函数调用或字段分配。
  • Pointcut:切入点,一个匹配连接点的正则表达式。 每当任何连接点匹配一个切入点时,就执行与该切入点相关联的指定增强。
  • Advice:增强,指特定连接点上执行的动作,实际中想要添加的功能,如日志、权限校验。有5种:@Before @After @AfterReturning @AfterThrowing @Around
  • Weaving:织入,即对方法的增强,将切面的代码织入(应用)到目标函数的过程。

Spring AOP 和 AspectJ

下表总结了 Spring AOP 和 AspectJ 之间的关键区别:

Spring AOP AspectJ
在纯 Java 中实现 使用 Java 编程语言的扩展实现
不需要单独的编译过程 除非设置 LTW,否则需要 AspectJ 编译器 (ajc)
只能使用运行时织入 运行时织入不可用。支持编译时、编译后和加载时织入
功能不强-仅支持方法级编织 更强大 - 可以编织字段、方法、构造函数、静态初始值设定项、最终类/方法等…。
只能在由 Spring 容器管理的 bean 上实现 可以在所有域对象上实现
仅支持方法执行切入点 支持所有切入点
代理是由目标对象创建的, 并且切面应用在这些代理上 在执行应用程序之前 (在运行时) 前, 各方面直接在代码中进行织入
比 AspectJ 慢多了 更好的性能
易于学习和应用 相对于 Spring AOP 来说更复杂

选择正确的框架

选择那个框架很大程度上取决于我们的要求:

  • 框架: 如果应用程序没有使用 Spring 框架, 那么我们就别无选择, 只能放弃使用 Spring AOP 的想法, 因为它无法管理任何超出 Spring 容器范围的东西。但是, 如果我们的应用程序是完全使用 Spring 框架创建的, 那么我们可以使用 Spring AOP, 因为它是简单的学习和应用。
  • 灵活性: 由于有限的 joinpoint 支持, Spring AOP 不是一个完整的 AOP 解决方案, 但它解决了程序员面临的最常见的问题。尽管如果我们想深入挖掘和开发 AOP 以达到其最大能力, 并希望得到广泛的可用 joinpoints 的支持, 那么最好选择 AspectJ。
  • 性能: 如果我们使用的是有限的切面, 那么就会有细微的性能差异。但有时, 应用程序有成千上万个切面的情况。我们不想在这样的情况下使用运行时编织, 所以最好选择 AspectJ。AspectJ 已知的速度比 Spring AOP 快8到35倍。
  • 两者的最佳之处: 这两个框架都是完全兼容的。我们总是可以利用 Spring AOP;只要有可能, 仍然可以在不支持前者的地方使用 AspectJ 获得支持。

基于我们的需求:对 Impala jdbc 驱动包的内容做增强。不受 Spring 管理,AspectJ 支持这种方式,并提供了 Compile-time weavingPost-compile weavingLoad-time weaving 三种织入方式,从开发部署便捷性上这里选择 Post-compile weaving 方式。

测试环境

Spring Boot: 2.1.4.RELEASE
Impala JDBC: 2.6.17.1020
mpala: 3.4

实现步骤:

步骤中省略了数据源的配置过程。驱动可以开启日志,有利于我们跟踪分析请求。

 jdbc:impala://localhost:21050;LogLevel=6;LogPath=/tmp/impala

1. 添加 aspects 支持

首先,我们通过 Maven 引入Spring 对 aspects 的支持:

    <!-- aspects -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
      <scope>compile</scope>
    </dependency>

上述依赖会自动引入 AspectJ,使用 AspectJ 实现 AOP 比较方便。

2. 定义切面类

然后,我们定义一个HS2ClientAspect

package com.cloudera.example.aspects;

import com.cloudera.example.helper.HS2ClientHelper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

/**
 * HS2ClientWrapper 类的切面。
 * <p>
 */
@Aspect
public class HS2ClientAspect {
   

  private final Logger log = LoggerFactory.getLogger(this.getClass());


  /**
   * 切入点,一个匹配连接点的正则表达式。
   */
  @Pointcut("execution(public * com.cloudera.impala.hivecommon.api.HS2ClientWrapper" +
      ".ExecuteStatement(..))")
  public void hs2Pointcut() {
   
    // Method is empty as this is just a Pointcut, the implementations are in the advices.
  }


  /**
   * 前置增强,目标方法执行前之前执行。
   *
   * @param joinPoint 连接点
   */
  @Before("hs2Pointcut()")
  public void optimizeQueryOption(JoinPoint joinPoint) {
   
    if (log.isDebugEnabled()) {
   
      log.debug("Enter: {}.{}() with argument[s] = {}",
          joinPoint.getSignature().
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值