gpt4 book ai didi

java - AspectJ 在切点中正式解除绑定(bind)

转载 作者:行者123 更新时间:2023-12-02 10:27:50 28 4
gpt4 key购买 nike

我有以下类(class):

public class Population {
private int population;

public Population()
{
population = 0;
}

public void newYear()
{
population += 10;
}

public int getPopulation() {
return population;
}
}

以及以下方面

public aspect StatisticsAspect {

private static int year = 0;

pointcut operation(Population caller) : call(* Population.newYear());

after(Population caller) : operation(caller)
{
System.out.println("New Year: " + year);
year++;

System.out.println("Population: " + caller.getPopulation());
}
}

现在我希望每次调用 newYear() 时,“统计信息”都会打印到控制台。不幸的是,我收到了 ajc:formal unbound in pointcut 错误。

我需要更改什么才能使其正常工作?

最佳答案

我对你的代码进行了一些重构,因为 getPopulation() 是一个坏名字并且违反了约定。顾名思义,返回的不是人口对象,而是人口的规模。

就您而言,命名caller也不好,因为对象不是调用者,而是被调用者或调用的目标。我只是将参数重命名为“population”,因为这次它确实包含一个“population”对象。然后我将其绑定(bind)到 target() 参数,以使错误消息消失。

我还从 call() 切换到 execution() 切入点,因为将代码编织到执行方法中而不是编织到执行方法的每个地方会更有效。方法被调用。

我还确保在第一个新年结束且人口增长后,计数从 1 开始,而不是从 0 开始。我通过使用 ++size 而不是 size++ 来做到这一点,即预增量而不是后增量。

现在代码如下所示:

package de.scrum_master.app;

public class Population {
private int size;

public Population() {
size = 0;
}

public void newYear() {
size += 10;
}

public int getSize() {
return size;
}

public static void main(String[] args) {
Population population1 = new Population();
population1.newYear();
population1.newYear();
Population population2 = new Population();
population2.newYear();
population2.newYear();
}
}
package de.scrum_master.aspect;

import de.scrum_master.app.Population;

public aspect StatisticsAspect {
private static int year = 0;

pointcut operation(Population population) :
execution(* Population.newYear()) && target(population);

after(Population population) : operation(population) {
System.out.printf("Population for year %d = %d%n", ++year, population.getSize());
}
}

现在查看控制台日志:

Population for year 1 = 10
Population for year 2 = 20
Population for year 3 = 10
Population for year 4 = 20

你能找出问题所在吗?您有一个总体年份计数器,但有多个人口。实际上,您应该为每个人口设置一年计数器,以便获得正确的统计数据。这可以通过每个目标(即每个群体)使用一个方面实例而不是单个方面来完成,当然也可以不再使年份计数器静态:

package de.scrum_master.aspect;

import de.scrum_master.app.Population;

public aspect StatisticsAspect pertarget(execution(Population.new(..))) {
private int year = 0;

pointcut operation(Population population) :
execution(* Population.newYear()) && target(population);

after(Population population) : operation(population) {
System.out.printf("%s size for year %d = %d%n", population, ++year, population.getSize());
}
}

这里,pertarget(execution(Population.new(..))) 的意思是:为每个 Population 构造函数执行创建一个方面实例,即每个创建的对象。

现在统计数据是正确的(我还稍微更改了日志消息以便打印对象 ID,以便我们可以看到哪条消息属于哪个群体):

de.scrum_master.app.Population@1d44bcfa size for year 1 = 10
de.scrum_master.app.Population@1d44bcfa size for year 2 = 20
de.scrum_master.app.Population@266474c2 size for year 1 = 10
de.scrum_master.app.Population@266474c2 size for year 2 = 20

关于java - AspectJ 在切点中正式解除绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53793975/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com