バインディング春のポストプロセッサのソースと春Awareのソースを、そしてソース春AOPを見てください。
スタートAOP
AOPの能力を有効にするには、このアノテーションを使用@EnableAspectJAutoProxy。それは@importインポートクラス使用AspectJAutoProxyRegistrarを、このクラスはImportBeanDefinitionRegistrarを実装し、それがConfigurationClassParserスキャン、およびキャッシュに追加されます。そして、キャッシュからConfigurationClassBeanDefinitionReader)は(その実装registerBeanDefinitionsの方法を実行する前に、クラスになるだろう。
AspectJAutoProxyRegistrar.registerBeanDefinitions()源码
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
}
上記の方法および構成ツールを使用すると、AOPは、あろうAopConfigUtils AnnotationAwareAspectJAutoProxyCreatorその名前がorg.springframework.aop.config.internalAutoProxyCreatorで、登録されたBeanFactory。
以下の図は、クラスの継承関係を示しAnnotationAwareAspectJAutoProxyCreator
それは見AnnotationAwareAspectJAutoProxyCreator BeanPostProcessorと認識し、その最上位の抽象クラスAbstractAutoProxyCreatorそのインターフェイスを実装していることができます。
プロキシオブジェクトを作成します
スプリング認識ソースクリア、BeanFactoryAware実装クラスでは、意志invokeAwareMethods()コールバックsetBeanFactory()メソッド、AnnotationAwareAspectJAutoProxyCreatorに注入DefaultListableBeanFactoryあります。
InstantiationAwareBeanPostProcessorは、後処理法postProcessBeforeInstantiation()とpostProcessAfterInstantiation()を添加し、これら2つの方法があろう定義されたメソッドBeanPostProcessor前に最初に呼び出される豆の初期化、前に。
- postProcessBeforeInstantiationは()反射ビーンのコンストラクタを呼び出す前に呼び出されます。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 会返回一个代理对象,会执行 postProcessBeforeInstantiation()
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
return doCreateBean(beanName, mbdToUse, args);
}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 从缓存获取
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 判断是否已经在 advisedBeans 缓存
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 判断 Bean 是否是 Advice/Pointcut/Advisor/AopInfrastructureBean 这些不需要代理的基础类型;或者是否 @Aspect 注解类
// 找到切面类中的所有通知方法,判断是否 AspectJPointcutAdvisor 类型,否则返回 false
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
return null;
}
- postProcessAfterInstantiation()メソッドは、IN)(populateBeanプロパティの割り当てを実行します。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
// 属性赋值,会执行 postProcessAfterInstantiation()
populateBean(beanName, mbd, instanceWrapper);
// 执行 BeanPostProcessor 的方法
return initializeBean(beanName, exposedObject, mbd);
}
- BeanPostProcessorアプローチのみでinitializeBean()で行われます。どのpostProcessAfterInitialization()メソッドは、すべての通知方法のセクションクラス、(例えば:強化されたプロキシオブジェクトを作成するための動的プロキシ技術の使用を取得します
com.xxx.Service$$EnhancerBySpringCGLIB$$e86c6525@57eda880
)、そしてそれはリターンが完了した後、コールバックメソッドを設定します。
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;
}
// 包装类
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 找到所有的候选通知方法
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 从候选通知方法找到可用于当前 Bean 的通知
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 获取所有的通知拦截器对象
Object[] specificInterceptors = eligibleAdvisors.toArray();
// 利用 AopProxy 来创建代理对象
// AopProxy 包含 JDK 和 CGLib 两种实现
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
この時点で、動的プロキシ・オブジェクトと完全作成、容器を向上プロキシオブジェクト、メソッドの実行を持っているであろう、また、通知方法を実行するためにプロキシオブジェクトを使用します。
プロキシオブジェクトを実行します
実行の方法は、薬剤である、CglibAopProxyインターセプタをブロックする、インターセプタチェーンは、このメソッドを取得しました。存在する場合インターセプタ鎖、CglibMethodInvocationはRETVAL、方法、すなわち、戻り値を返す前に実行され、すなわち、通知方法、進行()を実行し、オブジェクトの作成; NOインターセプタチェーン場合、直接メソッドを実行します。
インターセプターチェーンの方法は、実際に迎撃のArrayListキュー、最初のデフォルトExposeInvocationInterceptorを配置することで、デフォルトの順序の残りの部分はAspectJAfterThrowingAdvice、AspectJAfterReturningAdvice、AspectJAfterAdvice、AspectJAroundAdvice、AspectJMethodBeforeAdviceです。
通知のAspectJAroundAdvice、AspectJMethodBeforeAdviceタイプは、その反射通知方法によって直接行われる直面したときに進む()上記注文ArrayListの再帰呼び出しで、通知の他のタイプがすぐに実行されていない、それは、再帰呼び出しの呼び出しを待って再び戻ります()メソッド。したがって、我々は実行し、通知方法の順序を保証することができます:
>後サラウンド円形()が進む - 前に通知実行サラウンド(続行) - - >事前通知 - >リターン通知を実行する>方法 - - >ポスト通知を>メソッドが返します
概要
- @EnableAspectJAutoProxy使用@import(AspectJAutoProxyRegistrar.class)导入(AspectJAutoProxyRegistrar)ImportBeanDefinitionRegistrar。
- 容器リフレッシュは、invokeBeanFactoryPostProcessors()の実行(AspectJAutoProxyRegistrar)ImportBeanDefinitionRegistrar.registerBeanDefinitions()たBeanFactoryにAnnotationAwareAspectJAutoProxyCreatorを登録したとき。
- AnnotationAwareAspectJAutoProxyCreatorはたBeanFactoryにそれを登録し、invokeAwareMethods()コールバック(AbstractAdvisorAutoProxyCreator)BeanFactoryAware.setBeanFactory()メソッドを実行する)(registerBeanPostProcessorsに、InstantiationAwareBeanPostProcessorとBeanFactoryAwareを実現しました。
- finishBeanFactoryInitialization()の実行(AnnotationAwareAspectJAutoProxyCreator)BeanPostProcessor.postProcessAfterInitialization()、動的エージェント技術(ObjenesisCglibAopProxy / JdkDynamicAopProxy)を使用して、部分クラスとセクション通知方法を見つけ、拡張プロキシオブジェクトを作成するために拡張するクラスを切ります
com.xxx.Service$$EnhancerBySpringCGLIB$$e86c6525@57eda880
。 - 方法を実行するエージェントである場合、それはCglibAopProxyインターセプタ、インターセプタチェーンGETメソッド、順序再帰呼び出しをブロックする、通知方法は、異なる通知呼び出しシーケンスを達成するために、反射技術を用いて実行されます。