私は春AOPは非常に(それが唯一のSpring Beanあるクラスのパブリックメソッドにカットすることができ、そしてそれらのメソッドは、クラスの外から呼び出されたときのみ)にその能力が制限されていることを理解しています。インタフェースが含まれる場合しかし、今、私は別の不可解な制限を発見しました。
クラスがサブクラス化された場合、通常は、春AOPは、そのメソッド(でもオーバーライドされたもの)の全てに全く問題の切断を持っていません。
public class A {
public void methodA() { } //OK, can cut in
}
public class B extends A {
@Override
public void methodA() { } //OK, can cut in
public void methodB() { } //OK, can cut in
}
私たちはミックスにインターフェイスを追加する場合しかし、物事には、春AOPのためのかなり悪いを取得します:
public interface I {
public void methodA();
}
public class A implements I {
@Override
public void methodA() { } //OK, can cut in
public void methodB() { } //Fail, cannot see or cut into this method
}
public class B extends A {
@Override
public void methodA() { } //Fail, cannot see or cut into this method
public void methodC() { } //Fail, cannot see or cut into this method
}
まず第一に、春AOPは、インタフェースにあるメソッドに何かをカットすることができます-それは見ることができません。-第二には、それが唯一の直接インタフェースのメソッドを実装する方法にカットすることができますA.methodA()
。これはB.によって上書き同じ方法に切断することができません
私は、一般的なポイントカット表現を使用しています"execution(* method*(..))"
、それは表現の問題ではありませんので、すべての可能な方法にカットします。
この制限を回避する方法はありますか?または私はちょうど春AOPを忘れるとは異なるアプローチを使用する必要がありますか?
UPDATE: [OK]を、私は問題の本当の原因を発見しました。私は実際にこれをテストするためのIntelliJ IDEAのAOPのプラグインに頼りました。影響を受けるすべてのメソッドにポイントカットをリンクすることになっています。しかし、それは「古い」、ダイナミックJDKプロキシ戦略の代わりに、新しい、CGLIB戦略を使用していました。だから、すべてのメソッドにリンクされていませんが、私は実際に私のプログラムを実行したとき、それは正しく、すべてのメソッドにカットします。
私は「新しい」CGLIB戦略を使用しています春ブーツ2を、使用しています。それはまだ動作しない場合がありますので、しかし、SB1に、それはまだ、「古い」ダイナミックJDKプロキシ戦略を使用する場合があります。
春はAOPを実現するために、動的プロキシまたはCGLIBのいずれかを使用します。
CGLIBには、インターフェイスが存在しない場合、それが効果的にターゲットクラスのサブクラスを作成し、ターゲットクラスのすべてのメソッドをオーバーライドします選択されます。この方法では、すべてのメソッドは最終的なものであり、静的なものを除いて、中にカットすることができます。
ターゲット・クラスがインターフェースである場合には、その後、春には、インターフェースのいずれかを使用して、動的プロキシを使用するかもしれない、とapprantlyこれが唯一のインタフェースで宣言されたメソッドに影響します。
春ブート2.0前に、動的プロキシは、デフォルトの戦略です。今CGLIBは、ばねブート2.0後のデフォルトの戦略です。
おそらくあなたのケースでダイナミックプロキシアプローチを取る春に私には思えます。あなたは追加することができ、真:spring.aop.proxy-ターゲットクラスを強制使用CGLIBにごapplication.yamlに。
あなたはまだ問題がある場合、それはmothodsが呼び出されるかを示す、より完全なコードスニペットを投稿する方が良いでしょう。