記事ディレクトリ
1. @EnableAspectJAutoProxy を確認する
前の章で @EnableAspectJAutoProxy アノテーションのソース コードを確認すると、次のようになります。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
@EnableAspectJAutoProxy アノテーションは、@Import(AspectJAutoProxyRegistrar.class) を使用して、internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator という名前のコンポーネントをコンテナーに登録することが知られています。
また、次のように AnnotationAwareAspectJAutoProxyCreato クラスのコア継承関係も分析しました。
AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator(父类)
->AbstractAdvisorAutoProxyCreator(父类)
->AbstractAutoProxyCreator(父类)
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware(两个接口)
継承関係を見ると、このクラスは Spring Bean の初期化に関係する Aware インターフェースと BeanPostProcessor インターフェースを実装していることがわかります。そのため、このタイプの主な処理メソッドは の実装メソッドから来ていると推測されます。これら 2 つのインターフェイスです。同時に、このクラスは order メソッドも実装します。
- BeanPostProcessor: ポストプロセッサ、つまり、Bean の初期化が完了する前後に何かを実行します。
- BeanFactoryAware: BeanFactory を自動的に挿入します。
次に、AnnotationAwareAspectJAutoProxyCreator クラスの呼び出しプロセスを見てみましょう。具体的には、AnnotationAwareAspectJAutoProxyCreator が BeanPostProcessor としてどのような作業を行うか、および BeanFactoryAware としてどのような作業を行うかを見てみましょう。
2. AbstractAutoProxyCreator クラス
AnnotationAwareAspectJAutoProxyCreator クラスの継承関係から、SmartInstantiationAwareBeanPostProcessor インターフェースと BeanFactoryAware インターフェースが AbstractAutoProxyCreator クラスに実装されていることがわかります。
そこで、まず AbstractAutoProxyCreator クラスから解析します。
AbstractAutoProxyCreator クラスの定義から、AbstractAutoProxyCreator クラスが SmartInstantiationAwareBeanPostProcessor インターフェイスと BeanFactoryAware インターフェイスを直接実装していることがわかります。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
}
AbstractAutoProxyCreator は BeanFactoryAware インターフェースを実装するため、次に示すように AbstractAutoProxyCreator クラスに setBeanFactory() メソッドが必要です。
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
さらに、AbstractAutoProxyCreator クラスには BeanPostProcessor ポスト プロセッサに関連するメソッドがあります。それらは、postProcessBeforeInstantiation()、postProcessAfterInstantiation()、postProcessProperties()、postProcessBeforeInitialization()、postProcessAfterInitialization() です。全体的なソースコードは次のとおりです。
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)){
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
この時点で、AbstractAutoProxyCreator クラスでの BeanFactoryAware の実装と BeanPostProcessor ポストプロセッサの実装を確認しました。
次に、AbstractAutoProxyCreator の AbstractAdvisorAutoProxyCreator サブクラスを見てみましょう。
3. AbstractAdvisorAutoProxyCreator クラス
AbstractAdvisorAutoProxyCreator クラスには、次のコードがあります。
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
setBeanFactory() メソッドは AbstractAdvisorAutoProxyCreator クラスで書き換えられることに注意してください。そして、AbstractAdvisorAutoProxyCreator クラスの setBeanFactory() メソッドでは、AbstractAutoProxyCreator クラスの setBeanFactory() メソッドが最初に呼び出されます。
initBeanFactory() メソッドは setBeanFactory() メソッドでも呼び出され、initBeanFactory() メソッドの実装は次のとおりです。
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
さらに、AbstractAdvisorAutoProxyCreator クラスにはポスト プロセッサに関連するメソッドが見つかりませんでした。
次に、AbstractAdvisorAutoProxyCreator クラスのサブクラス AspectJAwareAdvisorAutoProxyCreator の分析を続けます。
4、AspectJAwareAdvisorAutoProxyCreator クラス
AspectJAwareAdvisorAutoProxyCreator クラスのソース コードを表示すると、AspectJAwareAdvisorAutoProxyCreator クラスにはポストプロセッサ関連のコードがないことがわかります。したがって、AspectJAwareAdvisorAutoProxyCreator クラスのサブクラス AnnotationAwareAspectJAutoProxyCreator の分析を続けます。
5、AnnotationAwareAspectJAutoProxyCreator クラス
AnnotationAwareAspectJAutoProxyCreator クラスでは、次のように initBeanFactory() メソッドを見つけることができます。
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
これを見て、友人たちは setBeanFactory の呼び出しプロセスについて少し理解しましたね。実際、setBeanFactory() の呼び出しプロセスは次のとおりです。まず、AbstractAdvisorAutoProxyCreator クラスの setBeanFactory() メソッドが実行され、その親クラス AbstractAutoProxyCreator の setBeanFactory() メソッドが、 AbstractAdvisorAutoProxyCreator クラスが呼び出され、その中で initBeanFactory() メソッドが呼び出されます。initBeanFactory() メソッドはサブクラス AnnotationAwareAspectJAutoProxyCreator で書き換えられるため、最終的に AnnotationAwareAspectJAutoProxyCreator クラスの initBeanFactory() メソッドが呼び出されます。AnnotationAwareAspectJAutoProxyCreator では、super.initBeanFactory(beanFactory) が最初に実行され、親クラス AbstractAdvisorAutoProxyCreator の initBeanFactory() メソッドが呼び出されます。
少し複雑なので、写真を見てみましょう。
上図の AbstractAdvisorAutoProxyCreator クラスの setBeanFactory() メソッドは、プログラム呼び出しのエントリ ポイントとして使用されていることに注意してください。このメソッドは、AbstractAutoProxyCreator#setBeanFactory() と AnnotationAwareAspectJAutoProxyCreator#initBeanFactory() を順番に呼び出してから、AnnotationAwareAspectJAutoProxyCreator# によって AbstractAdvisorAutoProxy を呼び出します。 initBeanFactory() 作成者#initBeanFactory( )。
さらに、AnnotationAwareAspectJAutoProxyCreator クラスにはポストプロセッサ関連のコードは見つかりませんでした。
さて、上記は解析した AnnotationAwareAspectJAutoProxyCreator クラスのソースコードです。次回の記事では、これらのソース コードの具体的な実行プロセスのデバッグを開始します。