spring AOP源码阅读:一、入口
aop的入口是AbstractAutoProxyCreator#postProcessBeforeInstantiation方法,代码如下
@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;
}
//TODO shouldSkip会查询所有候选Advisors,判断是否需要跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
//如果我们有一个自定义的TargetSource,那么在这里创建代理。
// 抑制目标bean不必要的默认实例化:TargetSource将以自定义方式处理目标实例。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//TODO 解析配置,获取Advice和Advisor(包含了Advice)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//TODO 创建aop代理,将增强功能List<Advisor>传入ProxyFactory代理工厂,生成动态代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
/**
* 生成了代理对象,jdk动态代理对象在执行方法的时候实际上执行的是
* {@link org.springframework.aop.framework.JdkDynamicAopProxy#invoke}方法
*/
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
在这里可以看出来AOP代理的大致逻辑
1.解析bean,获得增强方法并包装为Advisor(Advisor里面含有Advice,而Advice里面有增强方法的method,可以通过反射执行增强方法)。
2.将其传入代理工厂,创建对应的动态代理对象。
3.通过动态代理对象处理Advisors来执行增强方法(通过反射来调用增强方法和切点方法)。