我可以创建一个方面,以类似构建器的模式在构建器方法链的末尾注入一些代码吗?
最终目标是在方面内自动执行
build
方法(不一定是build
方法,而是任何其他代码),而不直接在代码中指定它。
这是一个最小的例子: 构建器界面:
public interface Builder {
Builder withArg1(Arg1 arg1);
Builder withArg2(Arg2 arg2);
...
Builder withArgN(ArgN argN);
void build();
}
方法链示例:
createBuilder().withArg2(arg2).withArg10(arg10)
预期的方面必须在
.withArg10(arg10)
方法之后执行。
你想要的,没有多大意义。看看你的例子:
createBuilder().withArg2(arg2).withArg10(arg10)
这只是源代码。编译后看起来是一样的
Builder builder = createBuilder();
builder = builder.withArg2(arg2);
builder = builder.withArg10(arg10);
AspectJ 是一个用于检测字节代码的工具。因此,它不会将其视为具有流畅 API 语法糖的单行源代码,而只是将其视为一堆方法调用。
现在,当我们稍微扩展示例代码时,如下所示:
Builder builder = createBuilder();
builder = builder.withArg2(arg2);
builder = builder.withArg10(arg10);
// Do something else
builder = builder.withArg3(arg3);
builder = builder.withArg7(arg7);
// Do something else
builder = builder.withArg5(arg5);
任何方面甚至源代码转换器如何知道您何时完成、在构建器上调用(流畅的 API)方法并准备好最终调用
builder.build()
?即使假设您将使用假设的工具来分析和转换源代码,这也将是一项艰巨的任务,因为用户总是可以选择单独调用构建器方法或在一个长链中调用构建器方法,或者混合使用两种方法,如下所示:
Builder builder = createBuilder().withArg2(arg2).withArg10(arg10);
// Do something else
builder = builder.withArg3(arg3).withArg7(arg7).withArg5(arg5);
你想要的不仅仅是技术挑战,但它根本没有多大意义。为什么您要剥夺用户决定何时完成调用构建器方法并准备好调用
build()
的决定权?一个方面怎么可能知道呢?为什么要在源代码中隐藏 build()
调用,记录用户的意图。尽管我很喜欢 AOP,但这里的这个用例不是一个横切问题,而是试图用锤子挖洞。