Spring中这么重要的AnnotationAwareAspectJAutoProxyCreator类是干嘛的?
大家好,我是冰河~~
停更了很久的【Spring注解系列】专题,终于重新更新了,我们还是接着之前的文章继续往下更新。在《【Spring注解驱动开发】二狗子让我给他讲讲@EnableAspectJAutoProxy注解》一文中,我们通过查看@EnableAspectJAutoProxy
注解的源码,如下所示。
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@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
-- ProxyProcessorSupport, SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
查看继承关系可以发现,此类实现了Aware
与BeanPostProcessor
接口,这两个接口都和Spring bean的初始化有关,由此推测此类主要处理方法都来自这两个接口的实现方法。同时该类也实现了order方法。
那今天,我们就来看看AnnotationAwareAspectJAutoProxyCreator
类的调用流程,具体来说,就是看看 ``AnnotationAwareAspectJAutoProxyCreator` 作为BeanPostProcessor做了哪些工作,作为BeanFactoryAware做了哪些工作。
分析AbstractAutoProxyCreator类
在 AnnotationAwareAspectJAutoProxyCreator
类的继承关系上可以看出, 是在AbstractAutoProxyCreator
类开始实现 SmartInstantiationAwareBeanPostProcessor
接口和 BeanFactoryAware
接口的。
所以,我们先来看看 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
类中找到了setBeanFactory()方法和getBeanFactory()方法。
另外,在 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
类中,存在后置处理器的逻辑。
到这,我们就在AbstractAutoProxyCreator
类中看到了BeanFactoryAware
的实现和后置处理器的实现。
接下来,我们再来看看AbstractAutoProxyCreator
的子类 AbstractAdvisorAutoProxyCreator
类。
分析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);
}
说明在AbstractAdvisorAutoProxyCreator
类中重写了setBeanFactory()方法。并且在AbstractAdvisorAutoProxyCreator
类的setBeanFactory()方法中,首先会调用AbstractAutoProxyCreator
类中的setBeanFactory()方法。
在setBeanFactory()方法中会调用initBeanFactory()方法,initBeanFactory()方法的实现如下所示。
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
initBeanFactory()方法的实现比较简单,这里,我就不多说了。
另外,我们并没有在AbstractAdvisorAutoProxyCreator
类中找到与后置处理器相关的方法。
接下来,我们继续分析AbstractAdvisorAutoProxyCreator
类的子类AspectJAwareAdvisorAutoProxyCreator类。
分析AspectJAwareAdvisorAutoProxyCreator类
通过查看AspectJAwareAdvisorAutoProxyCreator
类的源码,我们得知,在 AspectJAwareAdvisorAutoProxyCreator
类中没有与后置处理器相关的代码。所以,我们继续向上分析 AspectJAwareAdvisorAutoProxyCreator
类的子类 AnnotationAwareAspectJAutoProxyCreator
。
分析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()方法,在AbstractAdvisorAutoProxyCreator
类中的setBeanFactory()方法中会调用其父类AbstractAutoProxyCreator
中的setBeanFactory()方法,然后在AbstractAdvisorAutoProxyCreator
类中的setBeanFactory()方法中调用initBeanFactory()方法。由于在子类AnnotationAwareAspectJAutoProxyCreator
中重写了initBeanFactory()方法,最终调用的就是AnnotationAwareAspectJAutoProxyCreator
类中的initBeanFactory()方法。这么说有点绕,我们来看一张图吧。
注意,上图中的AbstractAdvisorAutoProxyCreator
类中的setBeanFactory()方法作为程序调用的入口,它会依次调用AbstractAutoProxyCreator#setBeanFactory()
和 AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()
,然后,再由 AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()
调用 AbstractAdvisorAutoProxyCreator#initBeanFactory()
。
除此之外,我们在AnnotationAwareAspectJAutoProxyCreator
类中,并没有发现与后置处理器相关的代码了。
好了,以上就是我们分析的有关AnnotationAwareAspectJAutoProxyCreator
类的源码。在下一篇文章中,我们开始debug调试这些源代码的具体执行流程。
好了,今天就到这儿吧,我是冰河,我们下期见~
Spring中这么重要的AnnotationAwareAspectJAutoProxyCreator类是干嘛的?的更多相关文章
- Spring中可以复用的工具类&特性记录
Spring 里有用工具类: GenericTypeResolver 解析泛型类型.核心逻辑还是调用 ResolvableTypeResolvableType 解析泛型类型 BeanWrapper 利 ...
- spring 中的两个DaoSupport类的使用对比
可以利用NamedParameterJdbcDaoSupport 已经封装的NamedParameterJdbcTemplate方便的进行sql中参数的初始化工作. 相对于JdbcDaoSupport ...
- Spring中提供的集合工具类util CollectionUtils
转自:https://blog.csdn.net/fangwenzheng88/article/details/78457850 CollectionUtils类 /* * Copyright 200 ...
- spring中订阅redis键值过期消息通知
1.首先启用redis通知功能(ubuntu下操作):编辑/etc/redis/redis.conf文件,添加或启用以下内容(过期通知): notify-keyspace-events Ex 或者登陆 ...
- Spring中获取数据库表主键序列
在程序开发中,我们经常有写数据库表的操作,数据表中经常带有主键自增序列,如何获取自增序列.spring中提供了相应的类 DataFieldMaxValueIncrementer. DataFieldM ...
- Spring中,使用Java配置的方式进行依赖注入
之前用spring的时候,只知道使用xml的方式,和使用注解的方式,却一直不知道在spring中,还可以使用Java类的方式进行配置.使用Java类的方式,就可以取代xml和注解.使用Java配置是S ...
- Spring 中StreamUtils教程
本文我们介绍StreamUtils类使用.StreamUtils是spring中用于处理流的类,是java.io包中inputStream和outputStream,不是java8中Steam.使用时 ...
- Spring中AOP相关源码解析
前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...
- Spring中通过变量和import标签来控制加载哪些bean
需求:根据设置变量,来加载某个spring的bean的配置文件,这个配置文件中,有某些使用的bean.在一些情况下,不希望这些bean被初始化和加载进context中,也不需要被外面访问到. 在spr ...
随机推荐
- Yarn 集群环境 HA 搭建
环境准备 确保主机搭建 HDFS HA 运行环境 步骤一:修改 mapred-site.xml 配置文件 [root@node-01 ~]# cd /root/apps/hadoop-3.2.1/et ...
- linux中cat、more、less命令区别详解##less 最合适最好用,和vim一样好用
linux中cat.more.less命令区别详解 caoxinyiyi关注 0.0362018.07.02 15:46:17字数 641阅读 516 linux中命令cat.more.less均可用 ...
- Linux进阶之排错
Permission denied 检查selinux长时间没有响应 防火墙 nginx和httpd可以自检nginx和httpd有日志 /var/log/nginx/ /var/log/httpd/ ...
- HEX与ASCII之间装换
static const char bcd_ascll[20]={0x30,0x31,0x32,0x33,0x34, 0x35,0x36,0x37,0x38,0x39, ...
- 重新整理 .net core 实践篇————配置系统之盟约[五]
前言 在asp .net core 中我们会看到一个appsettings.json 文件,它就是我们在服务中的各种配置,是至关重要的一部门. 不管是官方自带的服务,还是我们自己编写的服务都是用它来实 ...
- 对狂神说的MybatisPlus的学习总结
1.什么是MybatisPlus? 需要的基础:spring,spring mvc,mybatis 作用:可以节省大量的工作时间,所有的CRUD代码都可以自动完成,简化Mybatis MyBatis- ...
- MMF的初步介绍:一个规范化的视觉-语言多模态任务框架
在VQA, Image Caption等任务中,构建模型是一件工作量较大的工作.有没有什么能减少这些重复的工作量呢?与此同时,Pytorch,tensorflow等开源的深度学习工具包发布,大大减少了 ...
- 笔记-13-多线程 Thread方法 线程安全 生产者和消费者 死锁和阻塞 练习
题目1 编写程序,创建两个线程对象,一根线程循环输出"播放背景音乐",另一根线程循环输出"显示画面";要求: 1: 1个线程使用Runnable接口的匿名内部类 ...
- 五、SELinux安全防护
rwx 针对用户和组 SELinux 针对程序 targeted:定义网络程序规则 minimum:限制少量软件 mls:限制全部,没定义的全拒绝 [root@proxy ~]# vim ...
- 【NX二次开发】Block UI OrientXpress
属性说明 属性 类型 描述 常规 BlockID String 控件ID Enable Logical 是否可操作 Group ...