私は働いています:
Spring Framework
4.3.3AspectJ
1.8.9
次の通常のプロセスがあります。
@Controller
->@Service
->@Repository
について次のペアがありますAOP
。
PersonaServicePointcut
PersonaServiceAspect
シナリオは次のとおりです。
このクラスには、、 、@Service
などのメソッドが あります。それらは同じクラス内で一緒に宣言されます。delete
save
update
findOneById
delete
and update
throughなどのメソッドについては、 orアドバイスをAOP
使用してメソッドを呼び出しています。@Before
@Around
findOneById
その理由は、エンティティが存在しない場合にorメソッドを実行しても意味がないからです (Rest シナリオを検討してください)。したがって、例外をスローする必要があるため、 Exception Aとしましょう。delete
update
advice
@ControllerAdvice
この方法については、実質的に同じアプローチsave
が適用されています。したがって、メソッドを実行する前に、メソッドを再度呼び出して他save
のメソッドまたはアドバイスを実行します。エンティティが既に存在する場合は、例外をスローする必要があります。たとえば、 Exception Bをスローする必要があります。 @Before
@Around
findOneById
@ControllerAdvice
この方法を使用する 3 つのポイント/3 つのアドバイスがあることに注意してfindOneById
ください。エンティティが存在するかどうかを確認します。
例えば:
@Pointcut(value=
"execution(* mypackage.PersonaServiceImpl.saveOne(otherpackage.Persona))
&& args(persona)")
public void saveOnePointcut(Persona persona){}
@Pointcut(value=
"execution(*
mypackage.PersonaServiceImpl.updateOne(otherpackage.Persona))
&& args(persona)")
public void updateOnePointcut(Persona persona){}
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.deleteOne(String)) && args(id)")
public void deleteOnePointcut(String id){}
繰り返しますが、これら 3 つのアドバイスはメソッドを使用または実行しfindOneById
ます。
問題は、次のような新しいポイントカットを追加するときです。
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.findOneById(String))
&& args(id)")
public void findOneByIdPointcut(String id){}
このポイントカットを作成して、エンティティが既に存在するかどうかを確認しました。存在しない場合は、タイプの例外をスローする必要がありますC
(従来の 404 の場合)。
メソッド自体のまたはアドバイスを介してメソッドを実行するのは冗長なようです。しかし、これは目的とタイプ C の例外を作成するためにも必要です。一部の人が処理する必要がありますfindOneById
@Before
@Around
findOneById
logging
audit
@ControllerAdvice
問題は、メソッドの他のアドバイスが実行されるときです (メソッドも呼び出して実行することdelete/update/save
を思い出してください) my is execute unnecessarily .findOneById
findOneByIdPointcut
次のようなことを示すようにポイントカット宣言を変更する必要があります。
@Pointcut(Alpha)
public void findOneByIdPointcut(String id){}
どこAlpha
にある:
@Service
のfindOneById
メソッドの before/around アドバイスを実行しますが 、その呼び出しがクラスの他のアドバイスから実行された場合は決して実行しません。
PersonaServiceAspect
!execution
との!within
組み合わせで多くの方法を試しましたが、結果はありません。
のすべてのメソッドをそれぞれ固有のアドバイスでインターセプトするPointcut を1 つだけ作成した場合でも、パラメーターを使用して、どのメソッドが呼び出されたかを確認し、それぞれの制御を行うことができます。しかし、再びこの動作が発生します。 @Service
@Around
ProceedingJoinPoint proceedingJoinPoint
これは、次のことを意味します。
@Around("PersonaServicePointcut.anyMethodPointcut()")
public Object aroundAdviceAnyMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
どこanyMethodPointcut
ですかexecution(* mypackage.PersonaServiceImpl.*(..))
このアプローチを達成することは可能ですか?どのように?
ありがとう。