このドキュメントはSpring AOPとaspectjの断面を調べるためのドキュメントです。 Spring BootからSpringのProxy周りについては メモ書きしかないけどこちらをどうぞ
みんなだいすき AspectJAwareAdvisorAutoProxyCreatorから。 一番名前がそれっぽいからそこから見ていく。
AspectJAwareAdvisorAutoProxyCreatorのメソッドで、org.springframework.aop.Advisorのを受け取っているメソッドがあった。
org.springframework.aop.Advisorというクラスがorg.aopalliance.aop.Adviceを返却していた。 AOP AllianceはAOPの実装の標準化のために使われているライブラリだと思っている。
Advice自体がcglibのinterceptorみたいなものになるはず。
今度はProxyの周りを見ていく
AspectJAwareAdvisorAutoProxyCreator の親を辿っていく。 --> AbstractAdvisorAutoProxyCreator --> AbstractAutoProxyCreator
AbstractAutoProxyCreatorにcreateProxyメソッドが存在する。 このメソッドの中で以下のような記述が出てくる
``java ProxyFactory proxyFactory = new ProxyFactory(); ... // 中略 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors);
今度はProxyFactoryのメソッドを見ていく。
getProxyというメソッドがある。
この中ではcreateAopProxyというメソッドを呼んでいる
このメソッドの中では
`getAopProxyFactory().createAopProxy(this)` という記述が出てくる
ちなみに、aopProxyFactoryは単にgetterで、コンストラクタではDefaultAopProxyFactoryが登場している。
このクラスではObjenesisCglibAopProxyとJdkDynamicAopProxyが出てきて
いい感じにProxyを作ってくれるようだ。
戻ってProxyFactoryのgetProxyへ。
次はcreateAopProxyの戻り値のgetProxyメソッドを追っていく。
GglibAopProxyの実装を見る。
getProxyメソッドを見ていく。
この中では以下のような記述が出てくる。
```java
Callback[] callbacks = getCallbacks(rootClass);
今度はgetCallbacksを見る なんかこの辺でAOPのインターセプターが設定されてそう。
じゃあどこからinterceptorの受け渡しをしているんだろう。 これはAbstractAutoProxyCreatorのcreateProxy経由で ProxyFactoryにaddAdvisorsしている この部分。
ProxyFactoryは ProxyFactory --> ProxyCreatorSupport --> AdvisedSupportの継承関係になっている。
AdvisedSupportはCglibAopProxy.advisedというフィールドの型と一致する。 そういうことなんだろう。 で、終わらすのももったいないので DefaultAopProxyFactoryを見直すとcreateAopProxyメソッドの引数にAdvisedSupportを受けている。
ここまでが、AdviseとCGLIB周りの話。
ここからAspectjの話を見ていく。
雑にaopallianceのInterceptorインターフェースの実装を調べる するとAspectJAfterAdviceとかが出てくる。 とりあえずこれを見て、今度はこのクラスのコンストラクタを呼び出しているところを調べる ReflectiveAspectJAdvisorFactoryというクラスのgetAdviceメソッドにたどりつく。 switch文でアノテーションによって分岐してAOPのAdviceへと変換されている部分が出てきた。
aspectjからAOP Allianceのインターフェースへ変換している部分はこの辺になるらしい。
getAdviceを呼び出す処理を探していこう。 AspectJAwareAdvisorAutoProxyCreatorのshouldSkipから呼ばれている。
以下のようなメソッドになっていた。
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
ここで重要なのはfindCandidateAdvisors()だろう。 メソッドを読んでいく。
以下のような実装になっていた。 AbstractAdvisorAutoProxyCreatorの中にあるようだ。
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
advisorRetrievalHelperはBeanFactoryAdvisorRetrievalHelper型のフィールドらしい。 このクラスのfindAdvisorBeansを読んでみる。 advisorNamesをキャッシュしつつ、AdvisorのBeanを探しているらしい。
それはそれとして普段はaspectjのポイントカットとインターセプターしか書かずにAOPの実現が出来ている。 この辺を変換しているクラスはどこなのか気になってきた。
今度はaspectjのアノテーションの探索とAdvisorへの変換をしているクラスを探していく。
org.aspectj.lang.annotation.Around のアノテーションを使っているところを探していこう。
なにやら、AbstractAspectJAdvisorFactoryのfindAspectJAnnotationOnMethodなどで使っているようだ。
この辺で迷子になった