1 前言
我们分析了AOP不管是XML配置还是注解方式的解析过程,这篇我们简单来说下AOP在Spring中对bean对象代理的一个切入时机,其实我们在讲解IOC的时候,已经点了一下这篇我们再来简单说一下。
2 源码分析
我们知道AOP有个核心类大哥AbstractAutoProxyCreator, 他实现了BeanPostProcessor的postProcessAfterInitialization方法,其实就是在这里进行bean的AOP织入的,我们来看下源码:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { @Override // bean 初始化后置处理方法 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { // 如果需要,为 bean 生成代理对象 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } /* 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类, 则不应该生成代理,此时直接返回 bean 也就是代理不能给自己再加代理 就是不套娃 */ if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 将 <cacheKey, FALSE> 键值对放入缓存中 缓存你懂的 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 为目标 bean 查找合适的通知器 // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); /* 若 specificInterceptors != null,即 specificInterceptors != DO_NOT_PROXY, 则为 bean 生成代理对象,否则直接返回 bean */ if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建代理 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); /* 返回代理对象,此时 IOC 容器输入 bean,得到 proxy。此时, beanName 对应的 bean 是代理对象,而非原始的 bean */ return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
以上就是 Spring AOP 创建代理对象的入口方法分析,过程比较简单,这里简单总结一下:
- 若 bean 是 AOP 基础设施类型,则直接返回
- 为 bean 查找合适的通知器
- 如果通知器数组不为空,说明bean需要代理,则为 bean 生成代理对象,并返回代理对象
- 若数组为空,则返回原始 bean即自己
3 小结
本篇我们简单了解下AOP的织入时机,接下来我们就看看AOP是如何筛选通知器的,并如何串联编排多个通知器的,休息一下,我们再继续。
标签:cacheKey,Spring,beanName,代理,Object,bean,源码,AOP From: https://www.cnblogs.com/kukuxjx/p/17136107.html