当前位置: 首页 > 知识库问答 >
问题:

在使用aspectj检测集合之前获取字段的旧值

东方和惬
2023-03-14

当使用aspectj我有以下切入点:

pointcut contentFieldSetter(DataModelEntity dme, Object newValue) : set(!static !final * DataModelEntity+.*)
            && target(dme) 
            && args(newValue)
            && !@annotation(ChildField);


    before(DataModelEntity dme, Object newValue) : contentFieldSetter(dme, newValue) {
         System.out.println(dme.getClass().getSimpleName()+ "." + thisJoinPoint.getSignature().getName()+ ": change detected");
    }

如果指定了字段中已经存在的相同值,也会调用此切入点。有没有有效的方法在设置和比较之前获取值,以便只有在有“真实”变化时才调用我的打印?

共有1个答案

汪同
2023-03-14

不幸的是,没有简单的方法可以做到这一点,例如通过将旧值绑定到advice参数。如果知道要访问哪个字段,只需访问当前值dme即可。myField来自特权方面,因为您已经绑定了目标(dme)。看看我的答案。

为了以更通用的方式实现它,您必须确定通知中的字段实例,并通过反射读取其值:

package de.scrum_master.aspect;

import org.aspectj.lang.SoftException;
import org.aspectj.lang.reflect.FieldSignature;

public privileged aspect MyAspect {
  void around(Object instance, Object newValue) :
    set(* *) && target(instance) && args(newValue)
  {
    Object oldValue;
    try {
      oldValue = ((FieldSignature) thisJoinPointStaticPart.getSignature()).getField().get(instance);
    } catch (IllegalArgumentException | IllegalAccessException e) {
      throw new SoftException(e);
    }
    if (oldValue == null && newValue != null || oldValue != null && !oldValue.equals(newValue))
      System.out.println(thisJoinPoint + ": " + oldValue + " -> " + newValue);
    proceed(instance, newValue);
  }
}

当然,您使用前()建议的变体比我的周围()变体更简单。如果您只想记录一些东西,并且不希望在继续之前修改值,那么前建议会更好。但是当尝试这个时,我在尝试访问该字段时得到了一个IllegalAccessExctive,尽管有特权方面。在周围建议中,它很简单地工作。我想我必须在AEX J源代码中对此进行调查。无论如何,这里是前建议的变通方法:

  before(Object instance, Object newValue) :
    set(* *) && target(instance) && args(newValue)
  {
    Object oldValue;
    try {
      Field field = ((FieldSignature) thisJoinPointStaticPart.getSignature()).getField();
      field.setAccessible(true);
      oldValue = field.get(instance);
    } catch (IllegalArgumentException | IllegalAccessException e) {
      throw new SoftException(e);
    }
    if (oldValue == null && newValue != null || oldValue != null && !oldValue.equals(newValue))
      System.out.println(thisJoinPoint + ": " + oldValue + " -> " + newValue);
  }
 类似资料:
  • 问题内容: 亲爱的所有人,我目前正在将Spring AOP(v4)和AspectJ与Load-Time-Weaver一起使用。 我目前正在寻找一种将脏标志机制添加到我的bean中的方法。因此,尽管II在使用我的bean的setter之前使用AOP来调用方法。我已经实现了,但是如何在修改之前访问旧的字段值?还是有一种获取字段名称的方法,以便我可以在调用setter之前先调用getter? 有人可以在

  • 我试图设置一个聊天应用程序,在其中你可以搜索随机的用户交谈。现在,firestore中的数据库结构如下: 集合“users”-文档“userid”-集合“conversations”-文档“conversationid”-字段“partner”,“lastmessage” 其次,我有一个集合“conversations”,其中包含对话中的所有消息。 我现在尝试做的是,当你按下一个按钮时,应用程序将

  • 本文向大家介绍ThinkPHP3.1新特性之字段合法性检测详解,包括了ThinkPHP3.1新特性之字段合法性检测详解的使用技巧和注意事项,需要的朋友参考一下 ThinkPHP3.1版增加了表单提交的字段合法性检测,可以更好的保护数据的安全性。这一特性是3.1安全特性中的一个重要部分。 表单字段合法性检测需要使用create方法创建数据对象的时候才能生效,具体有两种方式: 一、属性定义 可以给模型

  • 感谢任何在这件事上帮我的人。

  • 我想从引用的文档中获取字段值。Mongodb版本是3.4。 假设我有两个收藏foo和bar。Foo提到bar: 相应的条形码文档看起来像这样: 我尝试了以下聚合函数来归档此结果: 聚合功能: 但我的结果是这样的: 我试着用谷歌搜索它,我查看了mongodb文档,但没有找到解决方案。 是我错过了什么还是这不可能? 谢谢

  • 问题内容: 我正在创建一个应用程序,但遇到了问题。当我尝试使用此函数获取值时,我有一个返回值: 我不知道如何在中获取字段的值。如果我这样做: 我仅获取列的名称(),而不获取值。关于如何实现这一目标的任何建议? 问题答案: 我认为您可以忘记检查null。 而是检查是否有数据,然后使用游标访问列: 阅读Android教程可能也很有意义。记事本教程似乎很合适:http : //developer.and