在aop源码解析二:postProcessBeforeInstantiation博文中 我们花了很长的一个篇幅介绍一个方法shouldSkip
方法 虽然看名字很简单 但里面确实做了很多的事情 虽然最终也是没有去创建代理 但这些工作并不是白做的 解析完以后缓存起来了 后面就可以直接使用了 这次我们看下AnnotationAwareAspectJAutoProxyCreator##postProcessAfterInitialization(Object bean, String beanName)
方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
在这里看到了我们一直想看到的代理相关的代码 因为创建代理是一件耗时的事情 要做很多的解析 转换等工作 所以根据beanClass``beanName
作为缓存的key
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 因为寻找切面方法等操作是很浪费时间的操作 所以如果不必操作的话或者已经创建过代理的话 尽量提前返回
//已经创建过
if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {
return bean;
}
//本身是切面类
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 可以看出作者的思路是很清晰的 几句代码概括了要做的事情 然后在方法里面展开
// advice advisor pointcut 等之间的名次的区别与联系
// advice : action to take at a joinpoint
// 1. 寻找适合此bean的切面方法
// 2. 创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象 java动态代理或者是基于cglib的代理 cglib代理更高效
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
我们又看到了shouldSkip(bean.getClass(), beanName)
方法 跟我