简体   繁体   English

Java:Spring AOP和Refactoring

[英]Java: Spring AOP & Refactoring

So I'm starting to get into Spring AOP, and something occurred to me. 所以我开始进入Spring AOP,我发生了一些事情。 When configuring an aspect, the annotations all use Strings as parameters, rather than Class objects. 配置方面时,注释都使用字符串作为参数,而不是Class对象。

I bring this up because this means that an IDE (I use Eclipse, so I'll just refer to it here) won't be able to refactor the aspect properly. 我提出这个问题是因为这意味着IDE(我使用Eclipse,所以我在这里只是引用它)将无法正确地重构方面。 So if I have a class MyClass, with a method public void foo(), an example of a Spring AOP annotation would be this: 因此,如果我有一个类MyClass,使用方法public void foo(),Spring AOP注释的一个例子是:

@Before ("execution(public void package.MyClass.foo())")

Because the param in the annotation is a String, if I refactored the method name to public void foo2(), it would break the binding of this aspect. 因为注释中的参数是一个String,如果我将方法名重构为public void foo2(),它将破坏这个方面的绑定。

I've been scouring various forums and tutorials, but everywhere I look I just see String parameters, which suggests that's the only option here. 我一直在搜索各种论坛和教程,但在我看的每个地方我只看到字符串参数,这表明这是唯一的选择。 I guess you could work around this by being a bit more generic in how you declare the binding: 我想你可以通过在声明绑定方面更通用来解决这个问题:

@Before ("exeuction(public void package.MyClass.set*(..))")

This new one will work for any setter method in MyClass, with any number of parameters (or no params). 这个新的将适用于MyClass中的任何setter方法,具有任意数量的参数(或没有参数)。 Of course, being vague like this might not work all the time. 当然,像这样模糊可能不会一直有效。

Anyway, I'm ranting a little bit here, it's late and I'm kind of tired and my brain is all worn out from hunting for an answer to this. 无论如何,我在这里咆哮一点,已经很晚了,我有点累了,我的大脑都因为寻找答案而疲惫不堪。 But my final question is this: is there any way to set up Spring AOP annotations so that refactoring will affect them? 但我的最后一个问题是:有没有办法设置Spring AOP注释,以便重构会影响它们?

Thanks. 谢谢。

Well, the whole point of AOP is to implement cross-cutting behaviour in a modular way and apply it to application code which ideally is unaware of any aspects. 好吧,AOP的重点是以模块化的方式实现交叉行为,并将其应用于理想情况下不知道任何方面的应用程序代码。 Thus, you have no fixed connection between the two. 因此,两者之间没有固定的连接。 It is just important to remember that as much as you maintain and refactor your application code, you should also refactor your aspects with it in oder to make sure that pointcuts do not break. 重要的是要记住,尽管你维护和重构你的应用程序代码,你也应该在oder中重构你的方面,以确保切入点不会破坏。

Having said that, Eclipse and other IDEs still give you hints about which aspects are applied where if you install AJDT (AspectJ Development Tools) . 话虽如此,Eclipse和其他IDE仍会提供有关在安装AJDT(AspectJ开发工具)时应用哪些方面的提示。 I mainly use full AspectJ , not the proxy-based "AOP lite" variant called Spring AOP , so I do not know if AJDT is any useful with Spring AOP. 我主要使用完整的AspectJ ,而不是基于代理的“AOP lite”变体,称为Spring AOP ,所以我不知道AJDT对Spring AOP是否有用。 It will be with AspectJ applied to Spring via LTW (load-time weaving), though. 但是,通过LTW(加载时织入)将AspectJ应用于Spring。

Here is a screenshot from "Aspect Visualisation" perspective : 以下是“Aspect Visualization”透视图的屏幕截图:

Eclipse中的Aspect可视化透视图

It graphically shows which aspects apply to which parts of the code. 它以图形方式显示哪些方面适用于代码的哪些部分。 If you double-click any of the dotted lines, a code editor will lead you to the exact place where an aspect is applied. 如果双击任何虚线,代码编辑器将引导您到应用方面的确切位置。

There also is the cross-reference view with little indicators within aspect code as well as plain Java code: 还有交叉引用视图 ,在方面代码和普通Java代码中都有很少的指示符:

Eclipse中的AJDT交叉引用视图,第1部分

On the right hand side there is the cross-reference view listing all aspects applying to the currently selected method. 在右侧有交叉参考视图,列出了应用于当前所选方法的所有方面。 On the left hand side there are little icons indicating which types of advice apply to each method. 在左侧有一些小图标,表明哪种类型的建议适用于每种方法。

BTW, the cross-reference view also works from aspects. 顺便说一下,交叉引用视图也可以从各个方面起作用。 When you place the cursor to within an advice, the xref view lists all places in the code where the advice applies: 将光标放在通知中时,外部参照视图会列出建议适用的代码中的所有位置:

Eclipse中的AJDT交叉引用视图,第2部分

There is more: The AspectJ compiler can be configured in such a way so as to list all joinpoints advised by aspect code. 还有更多:可以以这种方式配置AspectJ编译器 ,以便列出由方面代码建议的所有连接点。 You can check the output for changes manually or even in an automated smoke test. 您可以手动检查输出以进行更改,甚至可以在自动烟雾测试中检查。 For instance, if an advice does not apply anymore because you changed some package, class or method names, there will be an Xlint warning "adviceDidNotMatch" and/or sometimes also "invalidAbsoluteTypeName" . 例如,如果建议因为您更改了某些包,类或方法名称而不再适用,则会出现Xlint警告“adviceDidNotMatch”和/或有时也会出现“invalidAbsoluteTypeName” Furthermore, the cross-reference view for the advice in question will be empty: 此外,相关建议的交叉引用视图将为空:

AspectJ编译器警告

As you have just seen, there are plenty indicators and helpers within AJDT when refactoring application or aspect code. 正如您刚才所见,在重构应用程序或方面代码时,AJDT中有很多指标和帮助程序。

One more thing: If you use AspectJ instead of Spring AOP you have an option to use the more concise and expressive native AspectJ syntax instead of the annotation-style syntax. 还有一件事:如果您使用AspectJ而不是Spring AOP,您可以选择使用更简洁和富有表现力的原生AspectJ语法而不是注释样式语法。 I definitely prefer the former to the latter. 我绝对更喜欢前者和后者。 Then you have more than just strings in your code editor, better syntax highlighting and code completion and refactoring. 然后,您的代码编辑器中不仅包含字符串,还需要更好的语法突出显示以及代码完成和重构。

Last, but not least: You should also write unit and maybe integration tests for your aspect code so as to notice if aspects break. 最后,但并非最不重要:您还应该为您的方面代码编写单元测试和集成测试,以便注意方面是否中断。 Manual checks are nice, but automated regression tests are unbeatable when it comes to immediate feedback. 手动检查很不错,但是当涉及到即时反馈时,自动回归测试是无与伦比的。 ;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM