AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//获取expose_proxy_attribute属性
//并且转为布尔类型
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
//判断是否开启
if (exposeProxy) {
//如果开启了强制对切面进行曝光
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
下面就来看看是怎么强制使用的
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//从注册容器中去取出AOP切面的BeanDefinition
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//改变里面的属性
definition.getPropertyValues().add(“proxyTargetClass”, Boolean.TRUE);
}
}
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//从注册容器中去取出AOP切面的BeanDefinition
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//改变里面的属性
definition.getPropertyValues().add(“exposeProxy”, Boolean.TRUE);
}
}
可以看到,强制使用仅仅只是改变注册容器里面的AOP切面的BeanDefinition里面的属性
现在已经完成了AOP自动创建器的注册了,本来AOP自动创建器在Spring中的存储形式也是一个BeanDefinition,所以也需要注册后才能使用
上面已经将AOP自动创建器注册了,那么这个类到底做了什么工作来完成AOP的操作呢?接下来我们就对这个AnnotationAwareAspectJAutoProxyCreator进行分析
AnnotationAwareAspectAutoProxyCreator的架构
首先我们对这个类的整体架构进行分析

其关系大概是这样的
AnnotationAwareAspectJAutoProxyCreator继承了AspectJAwareAdvisorAutoProxyCreator,AspectJAwareAdvisorAutoProxyCreator又继承了AbstractAdvisorAutoProxyCreator,而AbstractAdvisorAutoProxy又继承了AbstractAutoProxyCreator
这个类实现了BeanPostProcessor接口,前面我们看Bean进行加载的时候,会去调用其PostProcessAfterInitialization方法(之前跳过了没去分析,所以现在知道了那个方法是针对切面类的BeanDefinition来进行处理的)
而postProcessAfrerInitialization方法却是在AbstractAutoProxyCreator来实现的
源码如下
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
//判断传进来的Bean是否为空
if (bean != null) {
//获取缓存的键名,这里的形式是beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//判断是否已经提前曝光代理过
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//如果没被代理过,执行wrapIfNecessart
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
//如果bean为Null,直接返回,如果不为null,但已经被曝光出来,直接返回bean
//解决了循环依赖的问题
return bean;
}
关键还是在于wrapIfNecessary方法上
wrapIfNecessary
该方法的作用就是进行给BeanDefinition进行代理增强的,并且会先判断有没有必要进行代理增强
源码如下
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//判断是不是已经增强过
//即targetSourcedBeans容器里面已经包含了这个BeanDefinition
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
//如果已经增强过,直接返回
return bean;
}
//判断是不是无需进行增强
//如果不位于advisedBeans里面,代表无需进行增强
//因为每个Bean加载的时候都会进入这个方法,切面的Bean肯定比事务的Bean少
//所以会将创建切面的Bean都存进advisedBeans容器中
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
//如果不需要增强,返回结果
return bean;
}
//判断该BeanDefinition是不是基础设施类,如果是基础设施类并且需要跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
//在advusedBeans容器中去存储该BeanDefinition
this.advisedBeans.put(cacheKey, Boolean.FALSE);
//value改为false,这也是前面第二个if判断的清空,如果是基础设施
return bean;
}
// Create proxy if we have advice.
//来到这里就证明需要给这个类建立切面了
//如果存在增强方法则要创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//判断是否存在增强方法,这里DO_NOT_PROXY是一个Null
if (specificInterceptors != DO_NOT_PROXY) {
//如果存在增强方法
//将

最低0.47元/天 解锁文章
1330

被折叠的 条评论
为什么被折叠?



