是否可以截获方法调用的参数和在其中进行方法调用的方法:AOP



我有一个DAO,它有一些使用org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate查询数据库的方法。这些方法中很少有某些方法参数,我想捕获从这些方法进行的数据库查询。我想编写一个 AOP,它将捕获从这些方法进行的 SQL 查询以及参数的值。下面是进行 jdbc 查询的方法之一(我需要捕获(: 我的道——

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中甚至可能吗?您还有其他解决方案吗?

我试图写在下面,但我只能捕捉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 {
//......
}

提前致谢

好的,只是为了让您了解什么是 MCVE 以及如果您只需要提供一个MCVE 是多么容易,我为您制作了一个。其实这是你的工作!下次请自己做。

你不连贯的片段没有告诉我要导入哪些类,如何定义和初始化像namedParameterJdbcTemplate这样的变量,如何配置你的 Spring 引导以及更多的事情。所以我不得不做出有根据的猜测并创建虚拟类,以便重现您的情况并测试我自己的解决方案。未经测试的解决方案是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);
}
}

控制台日志:

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会容易得多,绝对不会对您似乎认为自己是经验丰富的开发人员提出太多要求。这种权利感——"这里的开发人员没有什么比为自己创建一个运行示例更好的了,因为我太懒了。你是谁?国王?

最新更新