在执行之前使用 @AspectJ 修改 parseInt 参数。

huangapple go评论92阅读模式
英文:

Modify parseInt param before execution with @AspectJ

问题

I'm using spring boot 3.1.0 with org.springframework.boot:spring-boot-starter-aop

I can't make the aroundParseInt aspect to trigger.

I do another aspect test (test1) and this one is triggering.

What I trying to making is to intercept the param of the parseInt and modify it (needed).

import static java.lang.System.currentTimeMillis;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
public class TransformIntegerAspect {

    // THIS test aspect WORKS
    @Around("execution(* *(..)) && within(bknd.Siam.Dao.cobros.D_Cobros_Admin)")
    public Object test1(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        long startTime = currentTimeMillis();
        Object result = thisJoinPoint.proceed();
        System.out.println(thisJoinPoint + " -> " + (currentTimeMillis() - startTime) + " ms");
        LoggerManager.log("ISAAC measureExecutionTime");

        return result;
    }

    //this dont work
    @Around("execution(int java.lang.Integer.parseInt(String))")
    public Object aroundParseInt(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        String param = (String) args[0];

        // Modify the parameter before the call to Integer.parseInt
        String modifiedParam = modifyParam(param);

        args[0] = modifiedParam;

        Object result = joinPoint.proceed(args);

        return result;
    }

    private String modifyParam(String param) {
        // Your custom logic to modify the parameter
        // Return the modified parameter
        return param;
    }
    

The config file also has the @EnableAspectJAutoProxy(proxyTargetClass=true) and a Bean

    @Bean
    public TransformIntegerAspect transformParseIntAspect() {
        return new TransformIntegerAspect();
    }

I have some google code and cant make it works.

Also some people saids is possible and other saids is not.

"If they are made by 3rd party libraries, you can still use binary weaving, creating new versions of the 3rd party class files and creating replacement JARs for them. As an alternative, you can use LTW (load-time weaving) and weave them during class-loading." (https://stackoverflow.com/questions/69042565/spring-aop-with-aspectj-annotation).

I'm expecting to find if is really possible or not and an alternative way without making a utility method.

英文:

I'm using spring boot 3.1.0 with org.springframework.boot:spring-boot-starter-aop

I can't make the aroundParseInt aspect to trigger.

I do another aspect test (test1) and this one is triggering.

What I trying to making is to intercept the param of the parseInt and modify it (needed).

import static java.lang.System.currentTimeMillis;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
public class TransformIntegerAspect {

    // THIS test aspect WORKS
    @Around("execution(* *(..)) && within(bknd.Siam.Dao.cobros.D_Cobros_Admin)")
    public Object test1(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        long startTime = currentTimeMillis();
        Object result = thisJoinPoint.proceed();
        System.out.println(thisJoinPoint + " -> " + (currentTimeMillis() - startTime) + " ms");
        LoggerManager.log("ISAAC measureExecutionTime");

        return result;
    }

    //this dont work
    @Around("execution(int java.lang.Integer.parseInt(String))")
    public Object aroundParseInt(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        String param = (String) args[0];

        // Modify the parameter before the call to Integer.parseInt
        String modifiedParam = modifyParam(param);

        args[0] = modifiedParam;

        Object result = joinPoint.proceed(args);

        return result;
    }

    private String modifyParam(String param) {
        // Your custom logic to modify the parameter
        // Return the modified parameter\
        return param;
    }
    

The config file also has the @EnableAspectJAutoProxy(proxyTargetClass=true) and a Bean

    @Bean
    public TransformIntegerAspect transformParseIntAspect() {
        return new TransformIntegerAspect();
    }

I have some google code and cant make it works.

Also some people saids is possible and other saids is not.

"If they are made by 3rd party libraries, you can still use binary weaving, creating new versions of the 3rd party class files and creating replacement JARs for them. As an alternative, you can use LTW (load-time weaving) and weave them during class-loading." (https://stackoverflow.com/questions/69042565/spring-aop-with-aspectj-annotation).

Im expecting to find if is really possible or not and a alternative way without making a utility method.

答案1

得分: 1

Spring AOP 只能拦截 Spring beans/components 的方法,但您正在尝试拦截一个 JDK 方法。这已经有很多文档记录,并且在这里已经被问过很多次。下次请进行一些研究并阅读一些文档。

Native AspectJ 可以拦截它织入的任何类中的任何方法,但在使用加载时织入时,使用 JDK 类也可能会出问题,因为许多(不是全部)JDK 类在AspectJ织入代理之前加载,然后对于AspectJ来说修改它们就太晚了。一种间接的方式是织入调用代码,而不是包含并执行方法的类。在这种情况下,您将使用call而不是execution切入点。请注意,call在Spring AOP中不可用,这是使用原生AspectJ的原因之一。例如:

@Around("call(int java.lang.Integer.parseInt(String))")

在您的情况下,目标方法是静态的,这是您需要使用原生AspectJ的第三个原因,因为Spring AOP无法拦截静态方法。

英文:

Spring AOP can only intercept methods of Spring beans/components, but you are trying to intercept a JDK method. This is well-documented and has been asked here dozens of times before. Please do some research and read some documentation next time.

Native AspectJ can intercept any method in any class it is woven into, but with JDK classes this can also be a problem when using load-time weaving, because many (not all) JDK classes are loaded before the AspectJ weaving agent, and then it is too late for AspectJ to modify them. An indirect way is to weave the calling code, not the class containing and executing the method. You would use a call rather than an execution pointcut in that case. Please note that call is unavailable in Spring AOP, which is reason #2 to use native AspectJ. For example:

@Around("call(int java.lang.Integer.parseInt(String))")

In your case, the target method is static, which is reason #3 why you need native AspectJ, because again Spring AOP cannot intercept static methods.

huangapple
  • 本文由 发表于 2023年5月31日 23:41:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375226.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定