如何为 class 初始化定义切入点

How to define pointcut for class initialization

我是 AspectJ 的新手,正在尝试了解连接点模型 现在我有 class 这样的

public class Account {
 private static Map<String, PaymentMethod> supportedPayments = new HashMap<>();
 static {
   supportedPayments.add("COD", new CodPaymentMethod());
   supportedPayments.add("ATM", new ATMPaymentMethod());
 }
}

正如我从 AspectJ In Action 中读到的那样,有一种方法可以在初始化 class 时定义切入点,但我找不到语法。 有人帮帮我吗?

这个不行:

@Pointcut("initialization(com.jas.aop.bean.Payment"))

它说

ERROR] Syntax error on token "initialization(com.jas.aop.bean.Payment)", "name pattern" expected
/Users/admin/eclipse-workspace/aop/src/main/java/com/jas/aop/aspect/ClassInitializationAspect.java:9
@Pointcut("initialization(com.jas.aop.bean.Payment)")

你的切入点有几个问题:

  • 缺少右括号 )
  • initialization 拦截构造函数(即对象初始化)而不是静态 class 初始化,这不是您想要的,并且还需要构造函数模式,而不是 class 名称模式.
  • 如果您的方面恰好不在与目标 class 完全相同的包中,您必须使用完全限定的 class 名称,例如 my.package.Account,以便切入点匹配。

顺便说一下,您的代码片段只是伪代码,因为哈希映射没有 add 方法,而是 put 方法。示例 class 甚至无法编译。在这里发布问题时不要只是发明代码。让试图帮助您的人的生活更轻松。

现在这里有一个 MCVE,我总是建议您在问题中具体说明,以帮助人们重现您的情况。这次是我为你做的,这是你的免费机会。下次请自己动手

主要class使用的依赖class:

package de.scrum_master.app;

public interface PaymentMethod {}
package de.scrum_master.app;

public class ATMPaymentMethod implements PaymentMethod {}
package de.scrum_master.app;

public class CodPaymentMethod implements PaymentMethod {}

目标 class 驱动程序应用程序:

package de.scrum_master.app;

import java.util.HashMap;
import java.util.Map;

public class Account {
  private static Map<String, PaymentMethod> supportedPayments = new HashMap<>();

  static {
    System.out.println("Static initialiser block");
    supportedPayments.put("COD", new CodPaymentMethod());
    supportedPayments.put("ATM", new ATMPaymentMethod());
  }

  public Account() {
    System.out.println("Creating account");
  }

  public void doSomething() {
    System.out.println("Doing something");
  }

  public static void main(String[] args) {
    new Account().doSomething();
  }
}

看点:

方面同时显示 initializationstaticinitialization 以显示语法和功能上的差异。您可以在 AspectJ 手册中找到所有这些解释的示例,我强烈建议您阅读。

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AccountAspect {
  @Before("initialization(de.scrum_master.app.Account.new(..))")
  public void interceptObjectInitialisation(JoinPoint joinPoint) {
    System.out.println(joinPoint);
  }

  @Before("staticinitialization(de.scrum_master.app.Account)")
  public void interceptClassInitialisation(JoinPoint joinPoint) {
    System.out.println(joinPoint);
  }
}

控制台日志:

staticinitialization(de.scrum_master.app.Account.<clinit>)
Static initialiser block
initialization(de.scrum_master.app.Account())
Creating account
Doing something