我正在使用Spring AOP并且具有以下方面:
@Aspect
public class LoggingAspect {
@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("logBefore() is running!");
System.out.println("hijacked : " + joinPoint.getSignature().getName());
System.out.println("******");
}
}
Run Code Online (Sandbox Code Playgroud)
以上方面截获addCustomer
方法执行.addCustomer
method将string作为输入.但我需要记录传入addCustomer
方法内部的logBefore
方法输入.
有可能这样做吗?
Sot*_*lis 81
你有几个选择:
首先,您可以使用JoinPoint#getArgs()
返回Object[]
包含建议方法的所有参数的方法.您可能需要进行一些投射,具体取决于您要对它们执行的操作.
其次,您可以args
像这样使用切入点表达式:
// use '..' in the args expression if you have zero or more parameters at that point
@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..)) && args(yourString,..)")
Run Code Online (Sandbox Code Playgroud)
那么你的方法可以定义为
public void logBefore(JoinPoint joinPoint, String yourString)
Run Code Online (Sandbox Code Playgroud)
Rei*_*eus 18
是的,可以使用getArgs找到任何参数的值
@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
public void logBefore(JoinPoint joinPoint) {
Object[] signatureArgs = thisJoinPoint.getArgs();
for (Object signatureArg: signatureArgs) {
System.out.println("Arg: " + signatureArg);
...
}
}
Run Code Online (Sandbox Code Playgroud)
如果必须记录所有args或方法具有一个参数,则可以像前面的答案中所述简单地使用getArgs。
如果必须记录特定的arg,则可以对其进行注释,然后按以下方式恢复其值:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Data {
String methodName() default "";
}
@Aspect
public class YourAspect {
@Around("...")
public Object around(ProceedingJoinPoint point) throws Throwable {
Method method = MethodSignature.class.cast(point.getSignature()).getMethod();
Object[] args = point.getArgs();
StringBuilder data = new StringBuilder();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int argIndex = 0; argIndex < args.length; argIndex++) {
for (Annotation paramAnnotation : parameterAnnotations[argIndex]) {
if (!(paramAnnotation instanceof Data)) {
continue;
}
Data dataAnnotation = (Data) paramAnnotation;
if (dataAnnotation.methodName().length() > 0) {
Object obj = args[argIndex];
Method dataMethod = obj.getClass().getMethod(dataAnnotation.methodName());
data.append(dataMethod.invoke(obj));
continue;
}
data.append(args[argIndex]);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
public void doSomething(String someValue, @Data String someData, String otherValue) {
// Apsect will log value of someData param
}
public void doSomething(String someValue, @Data(methodName = "id") SomeObject someData, String otherValue) {
// Apsect will log returned value of someData.id() method
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以使用以下任一方法。
@Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String))")
public void logBefore1(JoinPoint joinPoint) {
System.out.println(joinPoint.getArgs()[0]);
}
Run Code Online (Sandbox Code Playgroud)
或者
@Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String)), && args(inputString)")
public void logBefore2(JoinPoint joinPoint, String inputString) {
System.out.println(inputString);
}
Run Code Online (Sandbox Code Playgroud)
joinpoint.getArgs() 返回对象数组。由于输入是单个字符串,因此只返回一个对象。
在第二种方法中,该名称应在表达和输入参数相同的通知方法,即args(inputString)
与public void logBefore2(JoinPoint joinPoint, String inputString)
此处,addCustomer(String)
表示具有一个 String 输入参数的方法。
如果为许多建议定义一个切入点,还有另一种方法,它可能会有所帮助:
@Pointcut("execution(@com.stackoverflow.MyAnnotation * *(..))")
protected void myPointcut() {
}
@AfterThrowing(pointcut = "myPointcut() && args(someId,..)", throwing = "e")
public void afterThrowingException(JoinPoint joinPoint, Exception e, Integer someId) {
System.out.println(someId.toString());
}
@AfterReturning(pointcut = "myPointcut() && args(someId,..)")
public void afterSuccessfulReturn(JoinPoint joinPoint, Integer someId) {
System.out.println(someId.toString());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
81833 次 |
最近记录: |