Можно ли перехватить аргументы вызова метода и метода, внутри которого сделан вызов метода: AOP - PullRequest
0 голосов
/ 27 мая 2018

У меня есть DAO, в котором есть несколько методов, которые делают запросы к базе данных, используя org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.У немногих из этих методов есть определенные аргументы метода, и я хотел бы захватить запросы к базе данных, сделанные из этих методов.Я хотел бы написать AOP, который будет захватывать запросы SQL, сделанные из этих методов, а также значение аргумента.Ниже приведен один из методов (который мне нужен для захвата), который делает запрос jdbc: Мой 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);

Мне нужно решение AOP, которое бы захватывало finalQuery и columnMap.Это возможно даже в АОП.Есть ли у вас какие-либо другие решения?

Я пытался написать ниже аспект, но я могу захватить только finalQuery, но не 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 {
//......
}

Заранее спасибо

1 Ответ

0 голосов
/ 29 мая 2018

Хорошо, просто для того, чтобы вы поняли, что такое MCVE и как легко предоставить его, если хотите, я сделал его для вас.На самом деле это была ваша работа! В следующий раз сделайте это самостоятельно, пожалуйста.

В ваших непоследовательных фрагментах не сказано, какие классы импортировать, какие переменные, например, namedParameterJdbcTemplate определены и инициализированы, как настроен ваш Spring Boot и многое другое.Поэтому я должен был сделать обоснованные догадки и создать фиктивные классы, чтобы воссоздать вашу ситуацию и проверить мое собственное решение.Непроверенные решения - это cr * p, поэтому вопрос заставляет меня делать подобные предположения.

То, что вы хотите реализовать, - это шаблон червоточины , см. Также мои ответы здесь и здесь , оба в собственном синтаксисе AspectJ.Я подготовил для вас синтаксис на основе аннотаций, который мне так не нравится, но который вы предпочитаете по какой-либо причине.

Классы вспомогательных вспомогательных файлов:

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);
  }
}

Консольlog:

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

Теперь, Амит, какого черта тебе было так трудно представить небольшой пример для пользы твоих SO-помощников, чтобы им не приходилось делать свою собственную работу длябесплатно в свободное время?Просто взять и починить свой собственный MCVE было бы намного проще, и определенно не нужно было бы спрашивать слишком много опытного разработчика, которым вы, кажется, думаете.Это чувство права: «Разработчикам здесь нет ничего лучше, чем создать работающий пример для себя, потому что я слишком ленив».- Я просто не понимаю.Кто ты?Король?

...