continue;
}
//判断普通增强是否适用
if (canApply(candidate, clazz, hasIntroductions)) {
//适用的话也添加进结果集中
eligibleAdvisors.add(candidate);
}
}
//返回结果集
return eligibleAdvisors;
}
从这里看到,原来增强器引介增强器、普通增强器之分
拓展:什么是引介增强器,对应我们常用的一些增强器的注解@Before、@After、@Around、@AfterThrowing、@AfterReturing,这些增强的对象都是针对方法级别的,当然我们可以将类的所有方法都被增强到,这也能达到类级别(这也是我们一般的方法,在方法规则式拦截里使用通配符来拦截所有的方法,但这也是一种不太完整的类级别),而引介增强,对应的则是对类级别的增强,我们可以通过引介增强来给目标类去添加新的属性、新的方法
具体使用的话可以参考这篇博客spring学习笔记(14)引介增强详解:定时器实例:无侵入式动态增强类功能_总结沉淀-CSDN博客_引介增强
里面有一个重要的点,就是引介增强的实现类要去实现引介增强接口IntroductionInterceptor,这也是为什么在上面会有IntroductionAdvisors之分了。。。。。。
而且这里还有一个比较重要的点,在判断普通增强是否适用的时候,已经对引介增强进行筛选了,而且此时的结果集是否为空,会影响普通增强的筛选,说白了就是hasIntroductions参数
下面就来看看canApply方法的细节
canApply方法
首先来看一下对于介质增强的canApply方法
并且可以看到,其调用了重载的方法,并且这个方法也是对于普通增强适用的canApply方法
该重载方法的具体源码如下
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//因为这里无论引介增强还是普通增强都是进入到该方法进行匹配
//所以下面也要进行区分开来
//个人总感觉这种设置不太好。。。。。。
//判断是不是引介增强
if (advisor instanceof IntroductionAdvisor) {
//如果是引介增强,进行匹配
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
//判断是不是普通增强
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//再次适用重载的canApply去进行匹配
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn’t have a pointcut so we assume it applies.
return true;
}
}
Emmmmm,后面的匹配过程太复杂了,没看懂。。。。。。
现在我们已经获取到了所有增强器了,下面就要开始创建切面了
返回到上面的AbstractAutoProxyCreator的wrapIfNecessary方法里面
现在我们已经完成了getAdvicesAndAdvisorsForBean方法,获取到了所有匹配的增强器,下面就是要给该Bean去创建代理对象了,注意这里不要搞混了,之前我们找代理对象是通过遍历容器里面的所有Bean去找到的,如今当前的Bean是准备被代理的Bean,此时ProxyFactory已经有了所有增强器和此时被代理的Bean的信息
createProxy方法
该方法的源码如下
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
//要注意,此时的bean是从IOC容器里面加载出来的Bean,已经是一个Object了
//这个bean代表的就是切面类的在IOC容器存储的Bean
//这里传进来的是这个bean的Class对象
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFa