AspectJ 形式在切点中未绑定
AspectJ formal unbound in cutpoint
我有以下 类:
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()
时,都将 "statistics" 打印到控制台。
不幸的是,我收到 ajc: formal unbound in pointcut
错误。
我需要更改什么才能使其正常工作?
我稍微重构了您的代码,因为 getPopulation()
是一个糟糕的名称并且违反了惯例。顾名思义,返回的不是人口对象,而是人口规模。
至于你的方面,命名caller
也不好,因为对象不是调用者,而是被调用者或调用的目标。我只是将参数重命名为 population
因为这次它真的包含了一个人口对象。然后我将它绑定到 target()
参数以使您的错误消息消失。
我还从 call()
切换到 execution()
切入点,因为将代码编织到执行的方法而不是调用方法的每个地方更有效。
我还确保在第一个新年结束并且人口增长后计数从 1 开始,而不是 0。我通过使用 ++size
而不是 size++
来做到这一点,即 pre- 而不是 post-increment.
现在代码如下所示:
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
我有以下 类:
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()
时,都将 "statistics" 打印到控制台。
不幸的是,我收到 ajc: formal unbound in pointcut
错误。
我需要更改什么才能使其正常工作?
我稍微重构了您的代码,因为 getPopulation()
是一个糟糕的名称并且违反了惯例。顾名思义,返回的不是人口对象,而是人口规模。
至于你的方面,命名caller
也不好,因为对象不是调用者,而是被调用者或调用的目标。我只是将参数重命名为 population
因为这次它真的包含了一个人口对象。然后我将它绑定到 target()
参数以使您的错误消息消失。
我还从 call()
切换到 execution()
切入点,因为将代码编织到执行的方法而不是调用方法的每个地方更有效。
我还确保在第一个新年结束并且人口增长后计数从 1 开始,而不是 0。我通过使用 ++size
而不是 size++
来做到这一点,即 pre- 而不是 post-increment.
现在代码如下所示:
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