加载机制
增强器并不是建一个加载器就加载的 ,他也是经过一系列匹配规则才最终过滤得到的。上文有讲了一个大概。在spring寻找增强器的时候,
AnnotationAwareAspectJAutoProxyCreator
中有一个实例BeanFactoryAspectJAdvisorsBuilder
已经在容器启动的时候加载好了当前可用的所有基于@Aspect
的增强器。 那么这个builder怎么有什么加载机制?这里面有自动代理和手动代理两种 。请看如下代码
/**
* Check whether the given aspect bean is eligible for auto-proxying.
* <p>If no <aop:include> elements were used then "includePatterns" will be
* {@code null} and all beans are included. If "includePatterns" is non-null,
* then one of the patterns must match.
*/
protected boolean isEligibleAspectBean(String beanName) {
//可以看到,如果没有在xml中通过配置指定增强器,则
//加载所有的@Aspect增强器。不进行过滤
if (this.includePatterns == null) {
return true;
}
//如果在xml文件中使用了定义的增强器,则优先使用include进来的aspect
else {
for (Pattern pattern : this.includePatterns) {
if (pattern.matcher(beanName).matches()) {
return true;
}
}
return false;
}
}
那我上文提到的拦截无效是什么原因呢 ? 其实就是这个加载机制的问题
因为项目之前已经通过xml做了指定,所以优先走xml中配置的aspect了。并没有装载sdk定义的缓存的切面类。所以就无法实现了。
解决的办法就是要么使用全部手动装载切面。要么全部用自动发现来装载。
如下:
<aop:aspectj-autoproxy>
<aop:include name="testAspect2"></aop:include>
</aop:aspectj-autoproxy>
如果有两个切面
testAspect2
testAspect1
,但是你在xml文件里面指定了一个,则另一个就不会起作用。
其实这是一种很奇怪的用法 。既然用了注解,为什么又要在xml中来声明哪些起作用? 其实目前很多代码都在一个过渡阶段,手动基于xml配置的bean和基于注解的bean在项目中是穿插使用的 。因为spring也对这种方式有支持。所以平时并没有什么问题。
网友评论