AOP动态代理解析2-代码织入入口
通过自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类到底做了什么工作来完成AOP的操作呢?首先我们看看AnnotationAwareAspectJAutoProxyCreator类的层次结构

在类的层级中,我们看到AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,而实现BeanPostProcessor后,当Spring加载这个Bean时会在实例化前调用其postProcessAfterInitialization方法,而对于AOP逻辑的分析也由此开始。
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
{
if(bean != null)
{
//根据给定的bean的class和name构建出个key,格式:beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if(!earlyProxyReferences.containsKey(cacheKey))
//如果它适合被代理,则需要封装指定bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)
{
//如果已经处理过
if(beanName != null && targetSourcedBeans.containsKey(beanName))
return bean;
//无需增强
if(Boolean.FALSE.equals(advisedBeans.get(cacheKey)))
return bean;
//给定的bean类是否代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
if(isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))
{
advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//如果存在增强方法则创建代理
Object specificInterceptors[] = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果获取到了增强则需要针对增强创建代理
if(specificInterceptors != DO_NOT_PROXY)
{
advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else
{
advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
函数中我们已经看到了代理创建的雏形。当然,真正开始之前还需要经过一些判断,比如是否已经处理过或者是否是需要跳过的bean,而真正创建代理的代码是从getAdvicesAndAdvisorsForBean开始的。
创建代理主要包含了两个步骤:
(1)获取增强方法或者增强器;
(2)根据获取的增强进行代理。
AOP动态代理解析2-代码织入入口的更多相关文章
- AOP静态代理解析2-代码织入
当我们完成了所有的AspectJ的准备工作后便可以进行织入分析了,首先还是从LoadTimeWeaverAwareProcessor开始. LoadTimeWeaverAwareProcessor实现 ...
- AOP动态代理解析4-代理的创建
做完了增强器的获取后就可以进行代理的创建了 AnnotationAwareAspectJAutoProxyCreator->postProcessAfterInitialization-> ...
- AOP动态代理解析1-标签的解析
spring.handlers http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespa ...
- AOP动态代理解析4-jdk代理的实现
JDKProxy的使用关键是创建自定义的InvocationHandler,而InvocationHandler中包含了需要覆盖的函数getProxy,而当前的方法正是完成了这个操作.在此确认一下JD ...
- AOP动态代理解析5-cglib代理的实现
CGLIB是一个强大的高性能的代码生成包.它广泛地被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的Interception(拦截).EasyMock和jMock是通过使 ...
- AOP动态代理解析3-增强方法的获取
对于指定bean的增强方法的获取一定是包含两个步骤的: 获取所有的增强 寻找所有增强中使用于bean的增强并应用 那么findCandidateAdvisors与findAdvisorsThatCan ...
- 30个类手写Spring核心原理之AOP代码织入(5)
本文节选自<Spring 5核心原理> 前面我们已经完成了Spring IoC.DI.MVC三大核心模块的功能,并保证了功能可用.接下来要完成Spring的另一个核心模块-AOP,这也是最 ...
- Spring的LoadTimeWeaver(代码织入)
在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入.类加载期织入和运行期织入.编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中:而类加载期织入则指通过特 ...
- Spring的LoadTimeWeaver(代码织入)(转)
https://www.cnblogs.com/wade-luffy/p/6073702.html 在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入.类加载期织入和运行期织入. ...
随机推荐
- Games:取石子游戏(POJ 1067)
取石子游戏 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37662 Accepted: 12594 Descripti ...
- KV6.60 SP1
组态王6.60 SP1全新发布! 组态王6.60 SP1对过去几年6系列中已解决过的故障进行了合并,包括各主线分支.各OEM版本中的故障总计122个,覆盖运行系统.开发系统.历史趋势曲线控件.报表.A ...
- java调用cmd命令删除文件夹及其所有内容
/** * *删除D盘下面test目录,感觉以前用io流遍历删除好慢! * **/ public static void main(String[] args) { Runtime run = Run ...
- August 10th, 2016, Week 33rd, Wednesday
The degree of loving is measured by the degree of giving. 爱的深浅是用给与的多少来衡量的. Some say that if you love ...
- Warp divergence
Threads are executed in warps of 32, with all threads in the warp executing the same instruction at ...
- 多线程编程3 - GCD
一.简介 在iOS所有实现多线程的方案中,GCD应该是最有魅力的,因为GCD本身是苹果公司为多核的并行运算提出的解决方案.GCD在工作时会自动利用更多的处理器核心,以充分利用更强大的机器.GCD是Gr ...
- Python--set常用操作函数
python提供了常用的数据结构,其中之一就是set,python中的set是不支持索引的.值不能重复.无需插入的容器. 简单记录下set常用的操作函数: 1.新建一个set: set("H ...
- NYOJ题目34韩信点兵
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAHiCAIAAACV1MbSAAAgAElEQVR4nO3dPXLjONeG4W8TyrUQx1 ...
- htnl中的遮罩层以及定位方式
在页面显示遮罩层,例如:一个div的css样式: $msk.css({ "top":"0", "left":"0", & ...
- ROW_NUMBER()函数的使用
SQL Server数据库ROW_NUMBER()函数的使用是本文我们要介绍的内容,接下来我们就通过几个实例来一一介绍ROW_NUMBER()函数的使用. 实例如下: .使用row_number()函 ...