是否可以使用 AOP/AspectJ 来影响 StringBuilder

Is it possible to use AOP/AspectJ to affect StringBuilder

我可以使用 AOP 强制每次使用 StringBuilder 时第一个插入的符号是 !!.

所以如果下面的代码在我的项目中的任何地方:

String sb = new StringBuilder().append("22").toString();

sb 实际上是 !!22

我的例子更关注日志记录:

@Component
@Aspect
class LoggingAspect {
    private final Log log = LogFactory.getLog(getClass());

    @Around("execution( * com.example..*.*(..) )")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        this.log.info("before " + pjp.toString());
        Object object = pjp.proceed();
        this.log.info("after " + pjp.toString());
    }
}

我遇到的问题是,是否可以为我的问题定义这样一个 joinpoint

是的,你可以。我不熟悉您当前使用的语法。但是使用 AspectJ 会是这样的:

public aspect InterceptStringBuilders {

    StringBuilder around(StringBuilder target) :
                  call(public StringBuilder append(String)) &&
                  !within(InterceptStringBuilders) &&
                  target(target)
                  {
                      if(target.length() == 0)
                      {
                         target.append("!!");
                      }
                      else if(target.length() == 1 || target.charAt(0) != '!' || target.charAt(1) != '!')
                      {
                         target.insert(0, "!!");
                      }
     
                      return proceed(target);
                 }
}  

连接点是 public StringBuilder append(String),您需要切入点 target 来公开 StringBuilder,以便您可以强制它以“!!”开头。此外,您还需要切入点 !within(interceptStringBuilders) 以确保您不会从方面本身拦截对 Stringbuilder 的调用。

我猜您使用的语法类似于:

"call(public StringBuilder append(String) && !within(LoggingAspect) && target(StringBuilder)"

一个运行例子:

Main.java :

public class Main {
    public static void main(String[] args) {
    System.out.println(new StringBuilder().append("22").toString());
    System.out.println(new StringBuilder().append("!2").append("!2").toString());
    System.out.println(new StringBuilder().append("!!2").append("!!2").toString());
    }
}

InterceptStringBuilders.aj:

public aspect InterceptStringBuilders {

    StringBuilder around(StringBuilder target) :
                  call(public StringBuilder append(String)) &&
                  !within(InterceptStringBuilders) &&
                  target(target){
                      if(target.length() == 0){
                         target.append("!!");
                      }
                      else if(target.length() == 1 || target.charAt(0) != '!' || target.charAt(1) != '!')
                      {
                         target.insert(0, "!!");
                      }
                      return proceed(target);
                 }
}  

输出:

!!22
!!!2!2
!!!!2!!2