Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @Aspect-getSignature()为空_Java_Aspect_Pointcut - Fatal编程技术网

Java @Aspect-getSignature()为空

Java @Aspect-getSignature()为空,java,aspect,pointcut,Java,Aspect,Pointcut,我创建了简单方面来计算特定方法的执行次数。我必须告诉你,我是第一次这样做,所以它可能不是很漂亮 首先,我创造了这样的东西: @Aspect @Component public class ItemAspect { private Map<String, Integer> functionsCalls = new HashMap<>(); public ItemAspect(){ this.functionsCalls.put("ItemA

我创建了简单方面来计算特定方法的执行次数。我必须告诉你,我是第一次这样做,所以它可能不是很漂亮

首先,我创造了这样的东西:

@Aspect
@Component
public class ItemAspect {
    private Map<String, Integer> functionsCalls = new HashMap<>();

    public ItemAspect(){
        this.functionsCalls.put("ItemApiController.addItem()", 0);
        this.functionsCalls.put("ItemApiController.getItems()", 0);
    }

    @Pointcut("execution(* io.swagger.api.ItemApiController.getItems(..))")
    private void itemApiControllerEx(){ }

    @After("itemApiControllerEx()")
    public void doAfterItemApiControllerEx (JoinPoint joinPoint) {
        this.functionsCalls.put(joinPoint.getSignature().toString(), this.functionsCalls.get(joinPoint.getSignature().toString())+1);
    }

    public Map<String, Integer> getFunctionsCalls () {
        return functionsCalls; }
}
它计算了getItems正确执行的次数。是的,除此之外,它也能工作。 但我想计算这两种方法,所以我将代码转换为:

@Aspect
@Component
public class ItemAspect {
    private Map<String, Integer> functionsCalls = new HashMap<>();

    public ItemAspect(){
        this.functionsCalls.put("ItemApiController.addItem()", 0);
        this.functionsCalls.put("ItemApiController.getItems()", 0);
    }

    @Pointcut("execution(* io.swagger.api.ItemApiController.*(..))")
    private void itemApiControllerEx(){ }

    @After("itemApiControllerEx()")
    public void doAfterItemApiControllerEx (JoinPoint joinPoint) {
        this.functionsCalls.put(joinPoint.getSignature().toString(), this.functionsCalls.get(joinPoint.getSignature().toString())+1);
    }

    public Map<String, Integer> getFunctionsCalls () {
        return functionsCalls; }
}

现在,当我尝试获取签名时,我得到了NullPointerException。有人能告诉我为什么会发生这种情况以及如何解决它吗

因为您没有共享您的应用程序代码-请了解什么是-我不能运行它,甚至不能查看您的应用程序类,但从我粗略地看一下您的方面代码可以看出,您正在尝试访问以下映射值:

functionsCalls.getjoinPoint.getSignature.toString 现在我猜测,您的目标类有两个以上您感兴趣的方法,并且在执行其中一个方法时,您的map access当然会为不存在的键的值返回null。因此,NullPointerException不是来自于尝试获取joinpoint签名,而是来自于尝试像这样增加null值:

myMap.GetNoneExistentValue+1//null+1=>NullPointerException 你应该更加防御性地编程

更新:这里是纯AspectJ中的一个方面,但是SpringAOP中的方面语法是相同的

包io.swagger.api; 公共类ItemApicController{ public void addItemObject项{} 公共对象getItems{ 返回假人; } 公共无效doSomethingElse{} } 包io.swagger.api; 导入java.util.Map; 公共类应用程序{ 公共静态无效字符串[]args{ ItemApicController控制器=新的ItemApicController; 控制员:addItemA; controller.getItems; controller.addItemB; controller.doSomethingElse; controller.addItemC; controller.getItems; controller.doSomethingElse; controller.addItemC; Map statistics=ItemAspect.getStatistics; 对于字符串签名:statistics.keySet System.out.printf%3d |%s%n,statistics.getsignature,signature; } } 包io.swagger.api; 导入java.util.HashMap; 导入java.util.Map; 导入org.aspectj.lang.JoinPoint; 导入org.aspectj.lang.annotation.After; 导入org.aspectj.lang.annotation.Aspect; 导入org.aspectj.lang.annotation.Pointcut; @面貌 公共类项目方面{ 私有静态映射methodCalls=新HashMap; @Pointcutexecution*io.swagger.api.ItemApicController.*。。 私有void itemApiControllerEx{} @AfteritemApiControllerEx 公共无效doAfterItemApiControllerExJoinPoint joinPoint{ 字符串签名=joinPoint.getSignature.toString; methodCalls.computeIfAbsentsignature,newSignature->0; methodCalls.putsignature、methodCalls.getsignature+1; } 公共静态地图统计{ 返回方法调用; } } 您可能会注意到,我重命名了一些东西,例如,在Java中,除了方法之外没有函数。我也没有在没有必要的时候一直使用它,并且删除了一些重复的代码。如果一个新的映射条目不存在,我就用0动态初始化它。如果您不知道如何读/写lambda表达式,您可能会觉得奇怪。您可以轻松地使用更经典的编程风格

如果methodCalls.ContainesKeySignature methodCalls.putsignature,0; 此外,我保留了您使用signature.toString作为映射密钥的想法,但是您也可以使用signature对象本身,或者可能先将它们强制转换为MethodSignature,然后您可以选择要提取哪个部分进行打印。但这只是锦上添花。字符串比完整签名对象占用更少的内存,所以这也很好

如果运行示例应用程序,将获得以下控制台输出:

2 | void io.swagger.api.ItemApiController.doSomethingElse 2 |对象io.swagger.api.ItemApicController.getItems 4 | void io.swagger.api.ItemApicController.addItemObject 更新2:还有另一种迭代映射的方法:使用其条目键/值对:

对于条目:statistics.entrySet System.out.printf%3d |%s%n,entry.getValue,entry.getKey;
是的,谢谢,我在几分钟前发现了这一点,然后回到这里写下了答案,当我看到你们的留言时,我找到了答案。感谢您的时间和MCVE,这将使以后提问更容易。此外,您的签名看起来不像ItemApicController.addItem,而是像void io.swagger.api.ItemApicController.addItemObject,因此这也无法工作。我将提供一个MCVE,为您提供一个干净的解决方案,只需几分钟。我添加了MCVE,让您了解更多关于Java编程的知识,因为您似乎是一个新手。我希望有帮助。