是否可以使用 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
我可以使用 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