gpt4 book ai didi

java - AspectJ Pointcut 用于采用可序列化类型或原始类型的任意数量参数的方法

转载 作者:行者123 更新时间:2023-12-01 10:17:11 28 4
gpt4 key购买 nike

如何为采用任意数量的参数(实现可序列化或原始类型)的方法编写切入点?

例如切入点应匹配:

methodA(String str, int i)
methodB(String str, String str2, List<String> list)

但不是

methodC(String str, DataX data)

其中 DataX 不可序列化

最佳答案

我不知道如何在切入点中指定这种条件,因此我为您提供的唯一东西非常昂贵,因为它涉及运行时检查 - 但它可以满足您的要求:

驱动程序应用程序:

package de.scrum_master.app;

import java.io.Serializable;

public class Application {
public static class MyNonSerializable {}

public static class MySerializable implements Serializable {
private static final long serialVersionUID = 1L;
}

private static MyNonSerializable one() {
return new MyNonSerializable();
}

static MySerializable two(int i, String string) {
return new MySerializable();

}

static String three(int i, String string, MyNonSerializable myNonSerializable) {
return "foo";
}

static MyNonSerializable four(int i, String string, MySerializable mySerializable) {
return new MyNonSerializable();
}

static void five(MyNonSerializable myNonSerializable) {
}

static int six(MySerializable mySerializable) {
return 11;
}

public static void main(String[] args) {
one();
two(11, "foo");
three(11, "foo", new MyNonSerializable());
four(11, "foo", new MySerializable());
five(new MyNonSerializable());
six(new MySerializable());
}
}

现在,无论返回类型如何,我们都希望拦截具有零个参数或任意数量的可序列化参数的执行。符合这个条件的方法有 mainonetwofoursix >.

运行时类型检查方面:

package de.scrum_master.aspect;

import java.io.Serializable;

public aspect MethodsWithSerializableArgumentsAspect {
before() : execution(* *(..)) {
boolean nonSerializableArgumentFound = false;
for (Object arg : thisJoinPoint.getArgs()) {
if (!(arg == null || arg instanceof Serializable)) {
nonSerializableArgumentFound = true;
break;
}
}
if (nonSerializableArgumentFound)
return;
System.out.println(thisJoinPoint);
}
}

控制台日志:

execution(void de.scrum_master.app.Application.main(String[]))
execution(Application.MyNonSerializable de.scrum_master.app.Application.one())
execution(Application.MySerializable de.scrum_master.app.Application.two(int, String))
execution(Application.MyNonSerializable de.scrum_master.app.Application.four(int, String, Application.MySerializable))
execution(int de.scrum_master.app.Application.six(Application.MySerializable))

塔达! :-)

现在,如果您还想排除返回不可序列化对象的方法,则应将输出限制为 maintwosix。你可以这样做:

package de.scrum_master.aspect;

import java.io.Serializable;

public aspect MethodsWithSerializableArgumentsAspect {
Object around() : execution(* *(..)) {
boolean nonSerializableArgumentFound = false;
for (Object arg : thisJoinPoint.getArgs()) {
if (!(arg instanceof Serializable)) {
nonSerializableArgumentFound = true;
break;
}
}
Object result = proceed();
if ((result == null || result instanceof Serializable) && !nonSerializableArgumentFound)
System.out.println(thisJoinPoint);
return result;
}
}

控制台日志:

execution(Application.MySerializable de.scrum_master.app.Application.two(int, String))
execution(int de.scrum_master.app.Application.six(Application.MySerializable))
execution(void de.scrum_master.app.Application.main(String[]))

请注意,为了对返回值进行运行时检查,我们只能在方法终止后打印结果。因此,main 位于日志输出的末尾,而不是像第一个解决方案那样位于开头。

更新:我忘了解释为什么我们需要检查null的参数和返回值。这是因为我们希望接受 nullvoid 作为 Serializable,但实际上 null instanceof Serialized 是 false。

<小时/>

更新 2 - 没有运行时类型检查的静态切入点解决方案:

好吧,我刚刚在吃一个苹果(不,它没有掉到我头上),突然有了这个想法。它实际上工作得很好并且正是您想要的:

package de.scrum_master.aspect;

import java.io.Serializable;

public aspect MethodsWithSerializableArgumentsAspect {
pointcut returnsSerializable() :
execution((Serializable+ || byte || short || int || long || float || double || char || boolean || void) *(..));

pointcut hasNonSerializableArguments() :
execution(* *(.., !(Serializable+ || byte || short || int || long || float || double || char || boolean || void), ..));

before() : returnsSerializable() && !hasNonSerializableArguments() {
System.out.println(thisJoinPoint);
}
}

顺便说一句,Serialized+ 表示“Serialized 及其所有子类或实现类”。

享受吧!

关于java - AspectJ Pointcut 用于采用可序列化类型或原始类型的任意数量参数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35825455/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com