是否可以拦截方法调用的参数以及在其中进行方法调用的方法:AOP [英] Is it possible to intercept arguments of a method call and method inside which the method call is made : AOP

查看:130
本文介绍了是否可以拦截方法调用的参数以及在其中进行方法调用的方法:AOP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DAO,它具有一些使用org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate对数据库进行查询的方法.这种方法很少有某些方法参数,我想捕获由这些方法产生的数据库查询.我想编写一个AOP,它将捕获从这些方法进行的SQL查询以及参数的值.以下是进行jdbc查询的方法之一(我需要捕获): 我的DAO-

I have a DAO that has some methods that make queries to a database using org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate. Few of this methods have certain method arguments and I would like to capture database queries made from these methods. I would like to write an AOP that would capture the SQL queries made from these methods along with the value of the argument. Below is one of the methods(that I need to capture) that makes jdbc query: My DAO-

public List<Map<String, Object>> getData(RequestParameters requestParameter, Map<String, Column> columnMap) {
    Map<String, Object> params = new HashMap<>();
    StringBuilder finalQuery = new StringBuilder();
    finalQuery.append(getDataQuery(requestParameter, columnMap, params));
    return namedParameterJdbcTemplate.queryForList(finalQuery.toString(), params);

我需要一个可以捕获finalQuerycolumnMap的AOP解决方案. 在AOP中甚至有可能做到这一点.您还有其他解决方案吗?

I need an AOP solution that would capture finalQuery and columnMap. Is that even possible in AOP. Do you have any other solutions?

我尝试写以下方面,但是我只能捕获finalQuery而不能捕获columnMap

I tried to write below aspect but I am able to only capture finalQuery but not columnMap

@Pointcut("withincode(public * com.abc.xyz..*.*(com.abc.xyz.RequestParameters, java.util.Map))")
private void anyGetDataMethodSignature() {
    // pointcut
}

@Pointcut("(call(* org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations.query*(..)) && within(com.abc.xyz.services..*.*))")
public void anyJDBCOperations() {
}

@Before("anyJDBCOperations() && anyGetDataMethodSignature()")
public void log(JoinPoint jp) throws Throwable {
//......
}

预先感谢

推荐答案

好的,只是为了让您了解 MCVE 是的,如果您只想要一个,提供它是多么容易,我为您提供了一个.实际上,这是 您的工作! .下一次请自己完成.

Okay, just in order to make you understand what an MCVE is and how easy it is to provide one if you only want, I made one for you. Actually this was your job! Next time do it by yourself, please.

您不连贯的代码片段不会告诉我要导入哪些类,如何定义和初始化像namedParameterJdbcTemplate这样的变量,如何配置Spring Boot以及其他更多内容.因此,我不得不进行有根据的猜测并创建虚拟类,以便重新创建您的情况并测试我自己的解决方案.未经测试的解决方案是cr * p,因此这是一个迫使我首先进行这种猜测的问题.

Your incoherent snippets do not tell me which classes to import, how variables like namedParameterJdbcTemplate are defined and initialised, how your Spring Boot is configured and many more things. So I had to make educated guesses and create dummy classes just so as to recreate your situation and test my own solution. Untested solutions are cr*p and so is a question forcing me to do that kind of guesswork in the first place.

您要实现的是虫洞模式,另请参见我的答案此处此处,均使用AspectJ本机语法.我为您准备的是我不喜欢的基于注释的语法,但是无论出于何种原因,您似乎都喜欢使用它.

What you want to implement is the wormhole pattern, see also my answers here and here, both in AspectJ native syntax. The one I prepared for you is in the annotation-based syntax I so dislike, but which you seem to prefer for whatever reason.

虚拟助手类:

package de.scrum_master.app;

public class RequestParameters {}

package de.scrum_master.app;

import java.util.List;
import java.util.Map;

public class DummyJdbcTemplate {
  public List<Map<String, Object>> queryForList(String string, Map<String, Object> params) {
    return null;
  }
}

package de.scrum_master.app;

public class Column {
  private String columnType;

  public Column(String columnType) {
    this.columnType = columnType;
  }

  @Override
  public String toString() {
    return "Column[columnType=" + columnType + "]";
  }
}

驱动程序应用程序:

package de.scrum_master.app;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Application {
  private DummyJdbcTemplate namedParameterJdbcTemplate = new DummyJdbcTemplate();

  public List<Map<String, Object>> getData(RequestParameters requestParameter, Map<String, Column> columnMap) {
    Map<String, Object> params = new HashMap<>();
    StringBuilder finalQuery = new StringBuilder();
    finalQuery.append(getDataQuery(requestParameter, columnMap, params));
    return namedParameterJdbcTemplate.queryForList(finalQuery.toString(), params);
  }

  public String getDataQuery(RequestParameters requestParameter, Map<String, Column> columnMap, Map<String, Object> params) {
    return "I am the final query";
  }

  public static void main(String[] args) {
    HashMap<String, Column> columnMap = new HashMap<>();
    columnMap.put("id", new Column("Long"));
    columnMap.put("name", new Column("VarChar"));
    columnMap.put("age", new Column("Int"));
    new Application().getData(new RequestParameters(), columnMap);
  }
}

关于实施虫洞模式:

package de.scrum_master.aspect;

import java.util.Map;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import de.scrum_master.app.Column;

@Aspect
public class MyAspect {
  @Pointcut(
    "execution(public * de.scrum_master.app..*(..)) && " +
    "args(de.scrum_master.app.RequestParameters, columns)"
  )
  private void anyGetDataMethodSignature(Map<String, Column> columns) {}

  @Pointcut(
    "call(* de.scrum_master.app.DummyJdbcTemplate.query*(..)) && " +
    "args(query, ..)"
  )
  private void anyJDBCOperations(String query) {}

  @Before(
    "anyJDBCOperations(query) &&" +
    "cflow(anyGetDataMethodSignature(columns))"
  )
  public void log(JoinPoint thisJoinPoint, Map<String, Column> columns, String query) throws Throwable {
    System.out.println(thisJoinPoint);
    System.out.println("  columns = " + columns);
    System.out.println("  query = " + query);
  }
}

控制台日志:

call(List de.scrum_master.app.DummyJdbcTemplate.queryForList(String, Map))
  columns = {name=Column[columnType=VarChar], id=Column[columnType=Long], age=Column[columnType=Int]}
  query = I am the final query

现在,阿米特(Amit),为您的SO帮助者的利益提供一个小例子对您来说有何困难,以至于他们不必在业余时间免费做自己的工作?仅仅选择并修复您自己的MCVE会容易得多,而且绝对不会问太多您似乎认为自己是有经验的开发人员.这种权利感-这里的开发人员没有比做一个自己的榜样更好的事了,因为我太懒了." -我不明白.你是谁?国王吗?

Now, Amit, what the heck was so difficult for you about providing a little example for your SO helpers' benefit, so they don't have to do your own job for free in their spare time? Just picking up and fixing your own MCVE would have been so much easier and definitely not asking too much of the experienced developer you seem to think you are. This sense of entitlement - "Developers here have nothing better to do than create a running example for themselves because I am too lazy." - I just don't get it. Who are you? A king?

这篇关于是否可以拦截方法调用的参数以及在其中进行方法调用的方法:AOP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆