一,AbstractAutoProxyCreator
1.BeanPostProcessor接口的两个方法
before方法没有内容,而该类的PostProcessAfterInitialization()方法,进行了操作
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey); //【入】
}
}
return bean;
}
这个方法是一个入口,重点是在wrapIfNecessary()方法上面:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
//判断是否需要 代理这个Bean
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//是否应该跳过,与实例化before()一样
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//1.获取匹配成功的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//2.创建代理
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;
}
二,获得匹配成功的Advisor类列表
判断是否需要代理: 位于子类AbstractAdvisorAutoProxyCreator类中
protected Object[] getAdvicesAndAdvisorsForBean(...) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
获得advisor
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //从Helper中获取。直接获取全部advisor
//筛选!【重点】
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
在第一步中,获得全部advisor,也就是通知类中的方法,注意这个时候方法里面的 pointcut只有一个string值
第二步,开始匹配,findAdvisorsThatCanApply()
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); //【入】
}
AopUtils类中:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) { //筛选添加
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
} //赛选 非该接口实现的advisor
boolean hasIntroductions = !eligibleAdvisors.isEmpty(); //空的,则设置未false
for (Advisor candidate : candidateAdvisors) { //再来一遍筛选
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}//第三个不再是默认值,表示是否处理,如果已经有值,则为true
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
这里主要是区分两个接口的实现,分别处理,下面看两个接口体系的不同“
IntroductionAdvisor接口体系:
pointcutAdvisor接口体系: 显然我们走该接口的if
核心方法在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;
return canApply(pca.getPointcut(), targetClass, hasIntroductions); //是否匹配切点表达式
}
else {
return true;
}
}
同样,我们走第二个if情况,再一次进行canApply()方法:
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
//【重点】
if (!pc.getClassFilter().matches(targetClass)) { //匹配
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
核心代码在第一行if中就已经体现了,两个方法,一个对具体的pointCut进行了实例化,第二个方法直接进行了匹配,提取告诉你,他们的具体实现都是交给了AspectJ包进行处理的!
-
处理pointCut
public ClassFilter getClassFilter() {
obtainPointcutExpression();
return this;
}
private PointcutExpression obtainPointcutExpression() {
if (getExpression() == null) { //表达式不存在,直接抛出异常
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
return this.pointcutExpression;
}
1.1.ClassLoader获取,类加载器,获取BeanFactory的类加载器。
private ClassLoader determinePointcutClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) { //走这里
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
if (this.pointcutDeclarationScope != null) {
return this.pointcutDeclarationScope.getClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
1.2.Expression实例化:
private PointcutExpression buildPointcutExpression(@Nullable ClassLoader classLoader) {
PointcutParser parser = initializePointcutParser(classLoader); //根据类加载器获得 解析器
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
for (int i = 0; i < pointcutParameters.length; i++) {
pointcutParameters[i] = parser.createPointcutParameter(
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
}
//解析,具体交给Aspect包
return parser.parsePointcutExpression(replaceBooleanOperators(resolveExpression()),
this.pointcutDeclarationScope, pointcutParameters);
}
2.匹配
public boolean matches(Class<?> targetClass) {
//获得切入点的详细信息
PointcutExpression pointcutExpression = obtainPointcutExpression();
try {
try { //交给Aspect 处理
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
return false;
}
到了此处,获得了匹配成功的Advisor类的时候,开始创建代理,请看下一节。