Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)

前面几篇博客中己经对切面表达式的解析,匹配己经做过详细的介绍了,今天我们来研究一下,当表达式和目标类方法匹配成功以后,又是如何创建代理的呢?今天,我们将围绕这个话题,再次来研究。先上示例。

AspectJTest

@Aspect
@Configuration
public class AspectJTest {
    @Before("execution(* com.spring_101_200.test_111_120.test_117_excution.excution1.*.*(..))")
    public void beforeTest() {
        System.out.println("beforeTest");
    }
}

今天我们主要分析Spring 是如何解析 execution(* com.spring_101_200.test_111_120.test_117_excution.excution1..(…)) 表达式。

MyService.java

@Service
public class MyService {
    public void service() {
        System.out.println("serivce");
    }
}

spring_117_excution1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">


    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <context:component-scan base-package="com.spring_101_200.test_111_120.test_117_excution.excution1"></context:component-scan>


</beans>

测试:

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_101_200/config_111_120/spring117_excution/spring_117_excution1.xml");
    MyService myService = ac.getBean(MyService.class);
    myService.service();
}

结果输出:

coding-Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)-

AbstractAutoProxyCreator.java

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		//从缓存中获取代理引用
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	
	if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	//如果advisedBeans己经包含,并对应的值是 false
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	//如果类是Advice或AopInfrastructureBean的子类 ,或者可以跳过aop,直接返回 bean,不创建代理
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	//获取切面拦截器
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	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());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	//如果通知器为空,直接返回不需要代理
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}
protected List findEligibleAdvisors(Class<?> beanClass, String beanName) {
	List candidateAdvisors = findCandidateAdvisors();
	List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		//对当前类对应的 advisor进行排序,这一步也很关键,比如类上配置了@Order注解,就在这里控制
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

AnnotationAwareAspectJAutoProxyCreator.java

protected List<Advisor> findCandidateAdvisors() {
	List<Advisor> advisors = super.findCandidateAdvisors();
	advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	return advisors;
}

AbstractAdvisorAutoProxyCreator.java

protected List<Advisor> findCandidateAdvisors() {
	return this.advisorRetrievalHelper.findAdvisorBeans();
}

BeanFactoryAdvisorRetrievalHelper.java

public List<Advisor> findAdvisorBeans() {
	//通知器名称列表
	String[] advisorNames = null;
	synchronized (this) {
		advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			//不要在这里初始化FactoryBeans:我们需要保留所有未初始化的常规bean,以使自动代理创建者对其应用!
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
	}
	if (advisorNames.length == 0) {
		return new LinkedList<Advisor>();
	}
	List<Advisor> advisors = new LinkedList<Advisor>();
	for (String name : advisorNames) {
		if (isEligibleBean(name)) {
			if (this.beanFactory.isCurrentlyInCreation(name)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping currently created advisor '" + name + "'");
				}
			}
			else {
				try {
					//将当前advisorNames 对应的bean 加入到 advisors 中
					advisors.add(this.beanFactory.getBean(name, Advisor.class));
				}
				catch (BeanCreationException ex) {
					Throwable rootCause = ex.getMostSpecificCause();
					if (rootCause instanceof BeanCurrentlyInCreationException) {
						BeanCreationException bce = (BeanCreationException) rootCause;
						if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
							if (logger.isDebugEnabled()) {
								logger.debug("Skipping advisor '" + name +
										"' with dependency on currently created bean: " + ex.getMessage());
							}
							continue;
						}
					}
					throw ex;
				}
			}
		}
	}
	return advisors;
}

BeanFactoryAspectJAdvisorsBuilder.java

public List<Advisor> buildAspectJAdvisors() {
	List<String> aspectNames = null;

	synchronized (this) {
		aspectNames = this.aspectBeanNames;
		if (aspectNames == null) {
			List<Advisor> advisors = new LinkedList<Advisor>();
			aspectNames = new LinkedList<String>();
			//获取当前容器中所有的 bean 名称
			String[] beanNames =
					BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
			for (String beanName : beanNames) {
				//如果没有资格 ,则跳过
				if (!isEligibleBean(beanName)) {
					continue;
				}
				//我们必须小心,不要急于实例化bean,因为在这种情况下,它们将被Spring容器缓存,但不会被编织
				Class<?> beanType = this.beanFactory.getType(beanName);
				if (beanType == null) {
					continue;
				}
				//是否有Aspect注解,有则加入到aspectNames
				if (this.advisorFactory.isAspect(beanType)) {
					aspectNames.add(beanName);
					AspectMetadata amd = new AspectMetadata(beanType, beanName);
					if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
						MetadataAwareAspectInstanceFactory factory =
								new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
						//发现当前类方法中是否配置了Before.class, Around.class, After.class, AfterReturning.class, 
						//AfterThrowing.class, Pointcut.class注解
						List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
						if (this.beanFactory.isSingleton(beanName)) {
							this.advisorsCache.put(beanName, classAdvisors);
						}
						else {
							this.aspectFactoryCache.put(beanName, factory);
						}
						advisors.addAll(classAdvisors);
					}
					else {
						//如果当前 bean 不是单例
						if (this.beanFactory.isSingleton(beanName)) {
							throw new IllegalArgumentException("Bean with name '" + beanName +
									"' is a singleton, but aspect instantiation model is not singleton");
						}
						MetadataAwareAspectInstanceFactory factory =
								new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
						this.aspectFactoryCache.put(beanName, factory);
						advisors.addAll(this.advisorFactory.getAdvisors(factory));
					}
				}
			}
			this.aspectBeanNames = aspectNames;
			return advisors;
		}
	}

	if (aspectNames.isEmpty()) {
		return Collections.emptyList();
	}
	List<Advisor> advisors = new LinkedList<Advisor>();
	for (String aspectName : aspectNames) {
		//从 advisors 缓存中获取
		List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
		if (cachedAdvisors != null) {
			advisors.addAll(cachedAdvisors);
		}
		else {
			//获取到工厂方法,再从工厂方法中获取 advisors
			MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
			advisors.addAll(this.advisorFactory.getAdvisors(factory));
		}
	}
	return advisors;
}

ReflectiveAspectJAdvisorFactory.java

private static final Comparator<Method> METHOD_COMPARATOR;

static {
	CompoundComparator<Method> comparator = new CompoundComparator<Method>();
	comparator.addComparator(new ConvertingComparator<Method, Annotation>(
			new InstanceComparator<Annotation>(
					Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
			new Converter<Method, Annotation>() {
				@Override
				public Annotation convert(Method method) {
					AspectJAnnotation<?> annotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
					return annotation == null ? null : annotation.getAnnotation();
				}
			}));
	comparator.addComparator(new ConvertingComparator<Method, String>(
			new Converter<Method, String>() {
				@Override
				public String convert(Method method) {
					return method.getName();
				}
			}));
	METHOD_COMPARATOR = comparator;
}

上面配置了的 comparator 主要是对方法进行排序。
1.配置了@Around, … @AfterThrowing注解的方法排在前面。没有配置的排在后面
2.配置了注解的方法,配置@Around注解的方法排在前面,配置了@AfterThrowing方法排在后面,如果配置相同注解,按照方法名排序,也就是 a方法名一定排在 b方法名前面。
3.没有配置注解,按照方法名排序。

@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
	final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
	final String aspectName = maaif.getAspectMetadata().getAspectName();
	validate(aspectClass);
	
	//我们需要用装饰器包装MetadataAwareAspectInstanceFactory ,以便仅实例化一次。
	final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
			new LazySingletonAspectInstanceFactoryDecorator(maaif);

	final List<Advisor> advisors = new LinkedList<Advisor>();
	//获取所有的通知器方法,排除配置了@Pointcut 注解的方法
	for (Method method : getAdvisorMethods(aspectClass)) {
		//找到配置了Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class
		//注解的方法,如果 advisor不为空,则加入到集合中
		Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}

	//如果 advisors 不为空,则判断当前类类型是否是pertarget,perthis,或pertypewithin,如果是,
	//则创建SyntheticInstantiationAdvisor,并加入到通知器最开始
	if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
		Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
		advisors.add(0, instantiationAdvisor);
	}

	//查找引介属性,如果属性中配置了DeclareParents注解,创建DeclareParentsAdvisor加入到当前通知器中
	for (Field field : aspectClass.getDeclaredFields()) {
		Advisor advisor = getDeclareParentsAdvisor(field);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}

	return advisors;
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
	final List<Method> methods = new LinkedList<Method>();
	ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
		@Override
		public void doWith(Method method) throws IllegalArgumentException {
			//获取所有没有配置 Pointcut 注解的方法
			if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
				methods.add(method);
			}
		}
	});
	//将所有的方法排序 ,先按照注解顺序,Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class,
	//如:配置了@Around注解的方法排在最前面,配置了@AfterReturning注解方法排在后面,如果同时配置了@Around注解,则
	//按方法名称排序,a方法名的在前,b 方法名的在后,ab 方法名在前,ac 方法名在后。
	//如果没有配置注解的方法,直接按照方法名排序 
	Collections.sort(methods, METHOD_COMPARATOR);
	return methods;
}
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
        int declarationOrderInAspect, String aspectName) {
	//再次做较验,比如
	//1.当前类父类配置了@Aspect注解,但是又不是抽象类,抛出异常
	//2.当前类没有配置@Aspect 注解
	//3.当前类的类型是percflow或percflowbelow,抛出 Spring 不支持此类 aop
    validate(aif.getAspectMetadata().getAspectClass());
    //获取当前方法的通知器
    AspectJExpressionPointcut ajexp = getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
    if (ajexp == null) {
        return null;
    }
    //第一个参数是AspectJAdvisorFactory,也就是 Advisor工厂。
    return new InstantiationModelAwarePointcutAdvisorImpl(
            this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }
    AspectJExpressionPointcut ajexp =
            new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
    return ajexp;
}

AbstractAspectJAdvisorFactory.java

protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
    Class<?>[] classesToLookFor = new Class<?>[] {
            Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
    for (Class<?> c : classesToLookFor) {
        AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class) c);
        if (foundAnnotation != null) {
            return foundAnnotation;
        }
    }
    return null;
}
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
    A result = AnnotationUtils.findAnnotation(method, toLookFor);
    if (result != null) {
        return new AspectJAnnotation<A>(result);
    }
    else {
        return null;
    }
}

AspectJAnnotation.java

//当前方法面配置注解
private final A annotation;
//当前方法的注解类型
private final AspectJAnnotationType annotationType;

private final String pointcutExpression;

private final String argumentNames;

static {
    annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
    annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
    annotationTypes.put(AfterReturning .class,AspectJAnnotationType.AtAfterReturning);
    annotationTypes.put(AfterThrowing .class,AspectJAnnotationType.AtAfterThrowing);
    annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
    annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
}

public AspectJAnnotation(A annotation) {
    this.annotation = annotation;
    this.annotationType = determineAnnotationType(annotation);
    try {
    	//注解表达式
        this.pointcutExpression = resolveExpression(annotation);
        //注解上配置了argNames的值,如
		//@Pointcut(value = "execution(* com..excution22.*.*(..))&& args(userName,..) " , argNames = "userName"),
		//这样配置的argNames的值userName,在这里通过反射调用注解的方法获取
        this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
    }
    catch (Exception ex) {
        throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
    }
}

private AspectJAnnotationType determineAnnotationType(A annotation) {
    for (Class<?> type : annotationTypes.keySet()) {
    	//如果当前注解类型是annotation,或者其子类,这里设计的非常巧妙
    	//如果我们自己写了一个注解,继承了@Before.class注解,也是可以实现切面的,方便我们业务扩展
        if (type.isInstance(annotation)) {
            return annotationTypes.get(type);
        }
    }
    throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
}

private String resolveExpression(A annotation) throws Exception {
    String expression = null;
    for (String methodName : new String[] {"value", "pointcut"}) {
        Method method;
        try {
        	//获取注解的value或者pointcut方法
            method = annotation.getClass().getDeclaredMethod(methodName);
        }
        catch (NoSuchMethodException ex) {
            method = null;
        }
        //如果方法不为空,反射获取 value 值或者 pointcut配置的值
        if (method != null) {
            String candidate = (String) method.invoke(annotation);
            if (StringUtils.hasText(candidate)) {
                expression = candidate;
            }
        }
    }
    return expression;
}


AspectJAnnotation这个类的构建,主要是将 advisor 的注解,注解类型,表达式,以及配置的argNames值初始化,在InstantiationModelAwarePointcutAdvisorImpl的实例化过程中,根据annotationType类型生成相应的 Advisor,下面我们来跟进InstantiationModelAwarePointcutAdvisorImpl的创建过程。

InstantiationModelAwarePointcutAdvisorImpl.java

public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
        MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
    this.declaredPointcut = ajexp;
    this.method = method;
    //初始化Advisor 工厂
    this.atAspectJAdvisorFactory = af;
    this.aspectInstanceFactory = aif;
    this.declarationOrder = declarationOrderInAspect;
    this.aspectName = aspectName;

    if (aif.getAspectMetadata().isLazilyInstantiated()) {
    	//如果切入点是延迟初始化
        Pointcut preInstantiationPointcut =
                Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
		//使其具有动态性:必须从实例化前状态更改为实例化后状态。 
		//如果不是动态切入点,则可以在第一次评估之后由Spring AOP基础结构对其进行优化。
        this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif);
        this.lazy = true;
    }
    else {
    	//如果aop为非惰性
        this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
        this.pointcut = declaredPointcut;
        this.lazy = false;
    }
}

private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
    return this.atAspectJAdvisorFactory.getAdvice(
            this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}

ReflectiveAspectJAdvisorFactory.java

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
        MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {

    Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
	
    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }

   	//是否是@Aspect注解类
    if (!isAspect(candidateAspectClass)) {
        throw new AopConfigException("Advice must be declared inside an aspect type: " +
                "Offending method '" + candidateAdviceMethod + "' in class [" +
                candidateAspectClass.getName() + "]");
    }

    if (logger.isDebugEnabled()) {
        logger.debug("Found AspectJ method: " + candidateAdviceMethod);
    }

    AbstractAspectJAdvice springAdvice;
	//获取当前注解类型
    switch (aspectJAnnotation.getAnnotationType()) {
        case AtBefore://如果方法配置了@Before,则创建AspectJMethodBeforeAdvice通知器
            springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
            break;
        case AtAfter: //如果方法配置了@After,则创建AspectJAfterAdvice通知器
            springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
            break;
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
            	//设置返回值名称
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
            	//设置异常名称
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        case AtAround:
            springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
            break;
        case AtPointcut://如果方法配置了@Pointcut,则不做任何处理
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method " + candidateAdviceMethod);
    }
	//设置切面名,如:AspectJTest#0
    springAdvice.setAspectName(aspectName);
    //设置当前方法在第几次调用,数值越小,方法调用时间越早
    springAdvice.setDeclarationOrder(declarationOrderInAspect);
    //从注解中获取参数名,从argNames,以逗号隔开
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(candidateAdviceMethod);
    }
    //绑定参数名
    springAdvice.calculateArgumentBindings();
    return springAdvice;
}

AbstractAspectJAdvice.java

public synchronized final void calculateArgumentBindings() {
	//方法参数个数
    if (this.argumentsIntrospected || this.adviceInvocationArgumentCount == 0) {
        return;
    }

    int numUnboundArgs = this.adviceInvocationArgumentCount;
    Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
    //如果第一个参数类型是JoinPoint或ProceedingJoinPoint类型
    if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
        numUnboundArgs--;
    }
	//如果第一个参数类型是JoinPoint.StaticPart
    else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
        numUnboundArgs--;
    }
	//如果参数个数还是大于0
    if (numUnboundArgs > 0) {
    	//绑定参数名
        bindArgumentsByName(numUnboundArgs);
    }
    this.argumentsIntrospected = true;
}
private void bindArgumentsByName(int numArgumentsExpectingToBind) {
    if (this.argumentNames == null) {
    	//获取参数名
        this.argumentNames = createParameterNameDiscoverer().getParameterNames(this.aspectJAdviceMethod);
    }
    if (this.argumentNames != null) {
        bindExplicitArguments(numArgumentsExpectingToBind);
    }
    else {
        throw new IllegalStateException("Advice method [" + this.aspectJAdviceMethod.getName() + "] " +
                "requires " + numArgumentsExpectingToBind + " arguments to be bound by name, but " +
                "the argument names were not specified and could not be discovered.");
    }
}
protected ParameterNameDiscoverer createParameterNameDiscoverer() {
	//添加默认的方法参数名发现类,
	//1.StandardReflectionParameterNameDiscoverer 标准反射参数名发现器,利用反射实现
	//2.LocalVariableTableParameterNameDiscoverer 本地变量表参数名发现器,这个主要是利用 ASM 技术,从常量池中读取方法参数名
    DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
    AspectJAdviceParameterNameDiscoverer adviceParameterNameDiscoverer =
            new AspectJAdviceParameterNameDiscoverer(this.pointcut.getExpression());
    adviceParameterNameDiscoverer.setReturningName(this.returningName);
    adviceParameterNameDiscoverer.setThrowingName(this.throwingName);
    adviceParameterNameDiscoverer.setRaiseExceptions(true);
    //3.加入自定义AspectJAdviceParameterNameDiscoverer方法参数名发现器
    discoverer.addDiscoverer(adviceParameterNameDiscoverer);
    return discoverer;
}
public String[] getParameterNames(Method method) {
	//先通过反射找方法参数名,如果找不到,通过 ASM 技术,从字节码常量池中查找方法参数名
	// 从常量池中读取方法参数,在之前的博客中己经详细讲解了字节码结构,Spring ASM 是如何读取 java字节码的
	// 这里就不再赘述了
    for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) {
        String[] result = pnd.getParameterNames(method);
        if (result != null) {
            return result;
        }
    }
    return null;
}
private void bindExplicitArguments(int numArgumentsLeftToBind) {
    this.argumentBindings = new HashMap<String, Integer>();
	//参数名个数不等于参数类型个数,抛出异常
    int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
    if (this.argumentNames.length != numExpectedArgumentNames) {
        throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames
                + " arguments to bind by name in advice, but actually found " +
                this.argumentNames.length + " arguments.");
    }

    //跳过方法参数JoinPoint或ProceedingJoinPoint类型,因为JoinPoint 只能配置在方法的第一个参数    
    int argumentIndexOffset = this.adviceInvocationArgumentCount - numArgumentsLeftToBind;
    for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
        this.argumentBindings.put(this.argumentNames[i], i);
    }
    
    if (this.returningName != null) {
    	//如果方法注解配置了returning,但是方法名中没有returningName,直接抛出异常 
        if (!this.argumentBindings.containsKey(this.returningName)) {
            throw new IllegalStateException("Returning argument name '"
                    + this.returningName + "' was not bound in advice arguments");
        }
        else {
            Integer index = this.argumentBindings.get(this.returningName);
            //设置方法的返回值类型
            this.discoveredReturningType = this.aspectJAdviceMethod.getParameterTypes()[index];
            //设置方法的泛型返回值类型
            this.discoveredReturningGenericType = this.aspectJAdviceMethod.getGenericParameterTypes()[index];
        }
    }
    if (this.throwingName != null) {
    	//同理,如果方法注解上配置了 throwing,而方法绑定参数名中没有该值,抛出异常
        if (!this.argumentBindings.containsKey(this.throwingName)) {
            throw new IllegalStateException("Throwing argument name '"
                    + this.throwingName + "' was not bound in advice arguments");
        }
        else {
            Integer index = this.argumentBindings.get(this.throwingName);
            //设置方法异常返回值类型
            this.discoveredThrowingType = this.aspectJAdviceMethod.getParameterTypes()[index];
        }
    }
	
    configurePointcutParameters(argumentIndexOffset);
}


private void configurePointcutParameters(int argumentIndexOffset) {
    int numParametersToRemove = argumentIndexOffset;
    if (this.returningName != null) {
        numParametersToRemove++;
    }
    if (this.throwingName != null) {
        numParametersToRemove++;
    }
    //去掉JoinPoint或ProceedingJoinPoint,和 returning,throwing 参数
    String[] pointcutParameterNames = new String[this.argumentNames.length - numParametersToRemove];
    //得到真正需要绑定的参数名和参数类型
    Class<?>[] pointcutParameterTypes = new Class<?>[pointcutParameterNames.length];
    Class<?>[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes();

    int index = 0;
    for (int i = 0; i < this.argumentNames.length; i++) {
    	//过虑掉JoinPoint或ProceedingJoinPoint
        if (i < argumentIndexOffset) {
            continue;
        }
        //过虑掉 returning和throwing 参数
        if (this.argumentNames[i].equals(this.returningName) ||
            this.argumentNames[i].equals(this.throwingName)) {
            continue;
        }
        //设置真正需要绑定的参数名和参数类型
        pointcutParameterNames[index] = this.argumentNames[i];
        pointcutParameterTypes[index] = methodParameterTypes[i];
        index++;
    }
    //将参数名和参数类型分别保存到pointcutParameterNames,和pointcutParameterTypes中
    //这些参数在后面进行切面调用时,肯定用得到的
    this.pointcut.setParameterNames(pointcutParameterNames);
    this.pointcut.setParameterTypes(pointcutParameterTypes);
}

方法进行到这里,己经得到了 Advisor 类型,并且进行了方法参数绑定。

AbstractAdvisorAutoProxyCreator.java

protected List<Advisor> findAdvisorsThatCanApply(
		List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
	ProxyCreationContext.setCurrentProxiedBeanName(beanName);
	try {
		return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
	}
	finally {
		ProxyCreationContext.setCurrentProxiedBeanName(null);
	}
}

AopUtils.java

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	if (candidateAdvisors.isEmpty()) {
		return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
	for (Advisor candidate : candidateAdvisors) {
		//引入增强(Introduction Advice)的概念:一个Java类,没有实现A接口,
		//在不修改Java类的情况下,使其具备A接口的功能。(非常强大有木有,A不需要动代码,就能有别的功能)
		//IntroductionAdvisor纯粹就是为Introduction而生的。
		//IntroductionAdvisor 和 PointcutAdvisor接口不同,它仅有一个类过滤器ClassFilter 而没有 MethodMatcher,
		//这是因为 `引介切面 的切点是类级别的,而 Pointcut 的切点是方法级别的(细粒度更细,所以更加常用)。
		//如果是引介增强,并且匹配成功
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	//如果配置了引介增强,而其他的 pointcut的matchs匹配的是 maybe,直接返回匹配成功
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			continue;
		}
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}
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;
		//如果是 PointcutAdvisor的实现类,则对方法级别匹配
		return canApply(pca.getPointcut(), targetClass, hasIntroductions);
	}
	else {
		return true;
	}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	Assert.notNull(pc, "Pointcut must not be null");
	//先对类级别匹配,如果不匹配返回 false,在这一步己经对切面表达式进行解析
	if (!pc.getClassFilter().matches(targetClass)) {
		return false;
	}

	MethodMatcher methodMatcher = pc.getMethodMatcher();
	IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
	if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
		introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
	}

	Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
	classes.add(targetClass);
	//对目标类中的每一个方法进行遍历
	for (Class<?> clazz : classes) {
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			if ((introductionAwareMethodMatcher != null &&
					//目标方法和切面表达式进行匹配,如果匹配成功,则返回 true 
					introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
					methodMatcher.matches(method, targetClass)) {
				return true;
			}
		}
	}
	return false;
}

AspectJAwareAdvisorAutoProxyCreator.java

protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
    List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
            new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());
    for (Advisor element : advisors) {
    	//初始化partiallyComparableAdvisors,DEFAULT_PRECEDENCE_COMPARATOR是AspectJPrecedenceComparator对象
        partiallyComparableAdvisors.add(
                new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
    }
    //开始真正的排序
    List<PartiallyComparableAdvisorHolder> sorted =
            PartialOrder.sort(partiallyComparableAdvisors);
    if (sorted != null) {
        List<Advisor> result = new ArrayList<Advisor>(advisors.size());
        for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
            result.add(pcAdvisor.getAdvisor());
        }
        return result;
    }
    else {
        return super.sortAdvisors(advisors);
    }
}

PartialOrder.java

public static List sort(List objects) {
    //如果切点个数是0个或者1个,没有必要排序
    if (objects.size() < 2) {
        return objects;
    }

    //创建新的比交对象 SortObject
    List<SortObject> sortList = new LinkedList<SortObject>(); // objects.size());
    for (Iterator i = objects.iterator(); i.hasNext();) {
        addNewPartialComparable(sortList, (PartialComparable) i.next());
    }

	//下面的代码,无非进行排序而已,分别获取objects[i]对应的切点而己
    final int N = objects.size();
    for (int index = 0; index < N; index++) {

        SortObject leastWithNoSmallers = null;

        for (Iterator i = sortList.iterator(); i.hasNext();) {
            SortObject so = (SortObject) i.next();
            if (so.hasNoSmallerObjects()) {
                if (leastWithNoSmallers == null || so.object.fallbackCompareTo(leastWithNoSmallers.object) < 0) {
                    leastWithNoSmallers = so;
                }
            }
        }
        if (leastWithNoSmallers == null) {
            return null;
        }
        removeFromGraph(sortList, leastWithNoSmallers);
        objects.set(index, leastWithNoSmallers.object);
    }
    return objects;
}

SortObject.java

private static void addNewPartialComparable(List graph, PartialComparable o) {
    SortObject so = new SortObject(o);
    for (Iterator i = graph.iterator(); i.hasNext();) {
        SortObject other = i.next();
        so.addDirectedLinks(other);
    }
    graph.add(so);
}
void addDirectedLinks(SortObject other) {
    int cmp = object.compareTo(other.object);
    if (cmp == 0) {
        return;
    }
    if (cmp > 0) {
        this.smallerObjects.add(other);
        other.biggerObjects.add(this);
    } else {
        this.biggerObjects.add(other);
        other.smallerObjects.add(this);
    }
}

PartiallyComparableAdvisorHolder.java

public int compareTo(Object obj) {
    Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
    return this.comparator.compare(this.advisor, otherAdvisor);
}

AspectJPrecedenceComparator.java

public int compare(Advisor o1, Advisor o2) {
    int advisorPrecedence = this.advisorComparator.compare(o1, o2);
    if (advisorPrecedence == 0 && declaredInSameAspect(o1, o2)) {
        advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
    }
    return advisorPrecedence;
}

OrderComparator.java

public int compare(Object o1, Object o2) {
	//这才是真正的匹配,我们在阅读 Spring 源码时,要注意一点,就是凡是 do 开头的方法才是真正做事情的方法,
	//其他的没有用 do 开头的,一般都是做一些辅助性的事情,比如初始化变量,参数较验等
    return doCompare(o1, o2, null);
}
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
	//如果o1通知器实现了PriorityOrdered接口,p1为 true 
    boolean p1 = (o1 instanceof PriorityOrdered);
    boolean p2 = (o2 instanceof PriorityOrdered);
    //只有一个通知器实现了PriorityOrdered接口,而另一个通知器没有实现PriorityOrdered接口,才能快速比对
    if (p1 && !p2) {
        return -1;
    }
    else if (p2 && !p1) {
        return 1;
    }

    int i1 = getOrder(o1, sourceProvider);
    int i2 = getOrder(o2, sourceProvider);
    return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
private int getOrder(Object obj, OrderSourceProvider sourceProvider) {
    Integer order = null;
    if (sourceProvider != null) {
        Object orderSource = sourceProvider.getOrderSource(obj);
        if (orderSource != null && orderSource.getClass().isArray()) {
            Object[] sources = ObjectUtils.toObjectArray(orderSource);
            for (Object source : sources) {
                order = findOrder(source);
                if (order != null) {
                    break;
                }
            }
        }
        else {
            order = findOrder(orderSource);
        }
    }
    return (order != null ? order : getOrder(obj));
}
protected int getOrder(Object obj) {
    Integer order = findOrder(obj);
    return (order != null ? order :0x7fffffff);
}

AnnotationAwareOrderComparator.java

protected Integer findOrder(Object obj) {
    Integer order = super.findOrder(obj);
    if (order != null) {
        return order;
    }

    if (obj instanceof Class) {
        return OrderUtils.getOrder((Class<?>) obj);
    }
    else if (obj instanceof Method) {
        Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class);
        if (ann != null) {
            return ann.value();
        }
    }
    else if (obj instanceof AnnotatedElement) {
        Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class);
        if (ann != null) {
            return ann.value();
        }
    }
    else if (obj != null) {
        return OrderUtils.getOrder(obj.getClass());
    }

    return null;
}
protected Integer findOrder(Object obj) {
	//如果当前 advisor是 Ordered实现类,则调用 getOrder()方法
    return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}

InstantiationModelAwarePointcutAdvisorImpl.java

public int getOrder() {
    return this.aspectInstanceFactory.getOrder();
}

LazySingletonAspectInstanceFactoryDecorator.java

public int getOrder() {
    return this.maaif.getOrder();
}

BeanFactoryAspectInstanceFactory.java

public int getOrder() {
    Class<?> type = this.beanFactory.getType(this.name);
    if (type != null) {
    	//如果当前类型是 Ordered 类的子类,并且是单例,直接调用该类的 getOrder()方法,
    	// 如:public class AspectJTest implements PriorityOrdered ,AspectJTest必需实现 getOrder()方法
        if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
            return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
        }
        //调用工具类的 getOrder()方法
        return OrderUtils.getOrder(type, 0x7fffffff);
    }
    return 0x7fffffff;
}

OrderUtils.java

public static Integer getOrder(Class<?> type, Integer defaultOrder) {
	//如果切点所在类有@Order注解,则获取@Order的 value 值作为属性值
    Order order = AnnotationUtils.findAnnotation(type, Order.class);
    if (order != null) {
        return order.value();
    }
    //如果没有配置@Order接口,则看切点所在类配置了javax.annotation.Priority注解,如果有,则获取@Priority注解的值
    Integer priorityOrder = getPriority(type);
    if (priorityOrder != null) {
        return priorityOrder;
    }
    //如果还不满足,直接使用默认值吧,调用顺序排在最后
    return defaultOrder;
}

读者看到这里,肯定很晕,写的是什么东西?但是认真的读者肯定能发现其中的规律,

    首先看当前切点是否是 PriorityOrdered的实现类,如果是,则排位靠前。如果两个切点所在类都有@Order注解,value 值,越小,排位越靠前。如果第一个切点所在类实现了PriorityOrdered接口,第二个切点所在类有@Order注解,则调用第一个切点所在类的 getOrder()方法获取返回值,与第二个切点所在类的@Order注解 value 值,进行比对,值越小,方法排位越靠前。如果第一个切点所在类实现了PriorityOrdered接口,第二个切点所在类没有@Order注解,同时也没有实现PriorityOrdered接口,则获取第一个切点所在类的 getOrder()方法的返回值与第二个切点默认值0x7fffffff,进行比对,(而0x7fffffff是整数的最大值,我们配置的时候,一般不会配置这么大的值),比对值越小,方法排位越在前。对于 getOrder()返回值相同的情况,该怎样么呢?下面的这个方法comparePrecedenceWithinAspect()就是来处理这种情况

AspectJPrecedenceComparator.java

private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
	//如果方法配置了@After,@AfterReturning,@AfterThrowing注解
    boolean oneOrOtherIsAfterAdvice =
            (AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
    int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);
    
    if (oneOrOtherIsAfterAdvice) {
        if (adviceDeclarationOrderDelta < 0) {
            return 1;
        }
        else if (adviceDeclarationOrderDelta == 0) {
            return 0;
        }
        else {
            return -1;
        }
    }
    else {
        if (adviceDeclarationOrderDelta < 0) {
            return -1;
        }
        else if (adviceDeclarationOrderDelta == 0) {
            return 0;
        }
        else {
            return 1;
        }
    }
}

根据下图,我们来分析一下,对于 ExposeInvocationInterceptor,系统默认是首先调用,这个不用多解析,而下面的7个方法都是在一个切面类AspectJTest中定义,下面是源码中的顺序。
        abeforeTest()
        beforeTest()
        afterTest()
        bafterTest()
        AfterReturning()
        afterThrowing()
        aroundTest()
刚开始通过调用这个方法
Collections.sort(methods, METHOD_COMPARATOR);
将所有的方法排序 ,先按照注解顺序,Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class,如:配置了@Around注解的方法排在最前面,配置了@AfterReturning注解方法排在后面,如果同时配置了@Around注解,则按方法名称排序,a方法名的在前,b 方法名的在后,ab 方法名在前,ac 方法名在后。如果没有配置注解的方法,直接按照方法名排序,经过上面方法调用,方法排序变成这样
coding-Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)-
而此时此刻第一个方法 aroundTest()方法的getAspectDeclarationOrder(advisor)对应的值是0,而 abeforeTest()方法的getAspectDeclarationOrder(advisor)值是1,getAspectDeclarationOrder(advisor)的值【advisors.size()】,即所在集合的索引位置,经过上面的辅垫,我们终于知道
int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);这一行代码是什么意思了。也就是如果当前方法没有配置注解@After,@AfterReturning,@AfterThrowing,则依然按之前的顺序。所以得到

    aroundTest(),abeforeTest(),beforeTest()三个方法的顺序相对不变。如果第一个切点方法配置了@After,而第二个切点方法没有配置,则第一个切点方法排位靠前。如果第一个切点方法配置了@After,而第二个切点方法也配置了@After,按照方法名降序,如 a ,b 方法,b 方法靠前,a 方法靠后,ab ,ac 方法,ac 方法靠前,ab 方法排位靠后。对于 a,b,c 方法分别配置了注解 @After, @AfterReturning, @AfterThrowing,则 c 方法最前,b 方法中间,a 方法最后。

经过上面分析,我们终于知道下图方法顺序是怎样来了的【这个顺序非常重要,直接关系到切点调用顺序】

        @AfterThrowing(pointcut = “test()”, throwing = “e”)
        public void afterThrowing(Exception e) {}
        @AfterReturning(“test()”)
        public void AfterReturning() {}
        @After(“test()”)
        public void bafterTest() {}
        @After(“test()”)
        public void afterTest() {}
        @Around(“test()”)
        public Object aroundTest(ProceedingJoinPoint p) {}
        @Before(“test()”)
        public void abeforeTest(JoinPoint jp) { }
        @Before(“test()”)
        public void beforeTest() { }
coding-Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)-

在这个方法中的两个 matchs,之前花了大量的时间来分析这两个方法,这里就不再多说了,到这里我们来总结一下,其实,上面的代码,看上去写了一大堆,其实,方法的原理很简单,就是 Spring 先去找到所有配置了 Aspect.class 注解的类,再在该类上找到所有配置了Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class注解的方法,将每个配置了以上注解的方法封装成一个 Advisor 对象,再调用 Advisor 的 canApply 方法,判断目标类方法是否和 Advisor 表达式匹配,如果匹配,则保存到 Advisor集合中,再对集合进行排序,排序的过程,会考虑到切点所在类是否配置了@Order注解。在代码查找的过程中,Spring加入大量缓存的使用,不过,这些也只是锦上添花而已,核心逻辑还是不变的。

AbstractAutoProxyCreator.java

protected Object createProxy(
		Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);
	//判断用户有没有配置proxyTargetClass为 true
	if (!proxyFactory.isProxyTargetClass()) {
		//目标 bean 中是否配置了preserveTargetClass为 true,如果配置了,使用 cglib 代理
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			//评估接口,如果当前类有接口,则加入到advisor 的interfaces中,如果没有,设置proxyTargetClass为 true,强制使用 CGlib 代理
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
	//将注解配置的通知器和普通的通知器合并
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	//将当前通知器加入到代理工厂的 advisors中
	for (Advisor advisor : advisors) {
		//将当前与类匹配的所有通知器加入到代理工厂的 advisors 中
		proxyFactory.addAdvisor(advisor);
	}
	//设置目标类为源类
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	//获取代理类
	return proxyFactory.getProxy(getProxyClassLoader());
}

ProxyFactory.java

public Object getProxy(ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
	if (!this.active) {
		activate();
	}
	return getAopProxyFactory().createAopProxy(this);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
		Class<?> targetClass = config.getTargetClass();
		if (targetClass == null) {
			throw new AopConfigException("TargetSource cannot determine target class: " +
					"Either an interface or a target is required for proxy creation.");
		}
		//如果目标类是接口或者是代理类,则使用 JDK动态代理,否则使用 Cglib代理
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}
public Object getProxy(ClassLoader classLoader) {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
	}

	try {
		Class<?> rootClass = this.advised.getTargetClass();
		Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

		Class<?> proxySuperClass = rootClass;
		if (ClassUtils.isCglibProxyClass(rootClass)) {
			proxySuperClass = rootClass.getSuperclass();
			Class<?>[] additionalInterfaces = rootClass.getInterfaces();
			for (Class<?> additionalInterface : additionalInterfaces) {
				this.advised.addInterface(additionalInterface);
			}
		}
		//验证该类,并根据需要编写日志消息。
		validateClassIfNecessary(proxySuperClass, classLoader);

		Enhancer enhancer = createEnhancer();
		if (classLoader != null) {
			enhancer.setClassLoader(classLoader);
			if (classLoader instanceof SmartClassLoader &&
					((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
				enhancer.setUseCache(false);
			}
		}
		enhancer.setSuperclass(proxySuperClass);
		enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));

		Callback[] callbacks = getCallbacks(rootClass);
		Class<?>[] types = new Class<?>[callbacks.length];
		for (int x = 0; x < types.length; x++) {
			types[x] = callbacks[x].getClass();
		}
		// 仅在上述getCallbacks调用之后,此时才会填充fixedInterceptorMap,
		//ProxyCallbackFilter这个非常重要,这个是 Spring aop 实现的关键类,
		enhancer.setCallbackFilter(new ProxyCallbackFilter(
				this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
		enhancer.setCallbackTypes(types);

		// 生成代理类并创建代理实例
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	catch (CodeGenerationException ex) {
		throw new AopConfigException("Could not generate CGLIB subclass of class [" +
				this.advised.getTargetClass() + "]: " +
				"Common causes of this problem include using a final class or a non-visible class",
				ex);
	}
	catch (IllegalArgumentException ex) {
		throw new AopConfigException("Could not generate CGLIB subclass of class [" +
				this.advised.getTargetClass() + "]: " +
				"Common causes of this problem include using a final class or a non-visible class",
				ex);
	}
	catch (Exception ex) {
		// TargetSource.getTarget() failed
		throw new AopConfigException("Unexpected AOP exception", ex);
	}
}

在上面方法中有一个 setCallbackTypes 方法,这个方法非常重要,这个方法向系统设置了动态代理拦截器,后面将根据方法信息,来动态匹配。

CglibAopProxy.java

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    //bean 的定义中是否配置了 <aop:aspectj-autoproxy expose-proxy="true">
    // 标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。
	// 当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。
    boolean exposeProxy = this.advised.isExposeProxy();
    // 标记该配置是否需要被冻结,如果被冻结,将不可以修改增强的配置。
	// 如果该值为true,那么代理对象的生成的各项信息配置完成,则不容许更改,
	//如果ProxyFactory设置完毕,该值为true,则不能对Advice进行改动,可以优化代理对象生成的性能。默认情况下该值为false
    boolean isFrozen = this.advised.isFrozen();
    //在本例中的TargetSource是AbstractAutoProxyCreator的wrapIfNecessary方法中 new SingletonTargetSource()对象,
    //因此,SingletonTargetSource的 isStatic 是 true
    boolean isStatic = this.advised.getTargetSource().isStatic();

    //aop 动态代理拦截器
    Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

    
    Callback targetInterceptor;
    if (exposeProxy) {
        targetInterceptor = isStatic ?
                new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
    }
    else {
        targetInterceptor = isStatic ?
                new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
    }

    //如果是单例,isStatic是静态的
    Callback targetDispatcher = isStatic ?
            new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
	//主拦截器链
    Callback[] mainCallbacks = new Callback[]{
        aopInterceptor, // for normal advice
        targetInterceptor, // invoke target without considering advice, if optimized
        new SerializableNoOp(), // no override for methods mapped to this
        targetDispatcher, this.advisedDispatcher,
        new EqualsInterceptor(this.advised),
        new HashCodeInterceptor(this.advised)
    };

    Callback[] callbacks;

    //如果是单例,又不可以修改增强配置
    if (isStatic && isFrozen) {
        Method[] methods = rootClass.getMethods();
        Callback[] fixedCallbacks = new Callback[methods.length];
        this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);

       	//创建fix拦截器链
        for (int x = 0; x < methods.length; x++) {
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
            fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                    chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
            this.fixedInterceptorMap.put(methods[x].toString(), x);
        }

        //合并拦截器链,将固定拦截器链放到调用链后面,如果既有动态拦截器链和静态拦截器链,先调用动态,再调用静态
        callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
        System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
        System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
        this.fixedInterceptorOffset = mainCallbacks.length;
    }
    else {
    	//直接获取动态拦截器链
        callbacks = mainCallbacks;
    }
    return callbacks;
}

coding-Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)-

ObjenesisCglibAopProxy.java

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
	Class<?> proxyClass = enhancer.createClass();
	Object proxyInstance = null;
	if (objenesis.isWorthTrying()) {
		try {
			//如果没有配置spring.objenesis.ignore,则创建代理实现
			proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
		}
		catch (Throwable ex) {
			logger.debug("Unable to instantiate proxy using Objenesis, " +
					"falling back to regular proxy construction", ex);
		}
	}

	if (proxyInstance == null) {
		try {
			//通过构造函数创建代理实例
			proxyInstance = (this.constructorArgs != null ?
					proxyClass.getConstructor(this.constructorArgTypes).newInstance(this.constructorArgs) :
					proxyClass.newInstance());
		}
		catch (Throwable ex) {
			throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
					"and regular proxy instantiation via default constructor fails as well", ex);
		}
	}
	((Factory) proxyInstance).setCallbacks(callbacks);
	return proxyInstance;
}

在创建代理类的过程非常复杂,这里就不做过多分析,我们只分析在 Spring 中代理到底做了哪些事情。
coding-Spring源码深度解析(郝佳)-学习-源码解析-aop代理创建(五)-
我们知道在创建代理过程中,设置了setCallbackTypes回调类型,在 cglib 中是如何调用的,我也不去做详细分析了,但是其主要表现是当CglibAopProxy代理方法accept(method),根据方法类型,如果方法返回0,将使用DynamicAdvisedInterceptor拦截器,如果返回6,则使用HashCodeInterceptor拦截器。

        types[0]:DynamicAdvisedInterceptor
        types[1]:StaticUnadvisedExposedInterceptor
        types[2]:SerializableNoOp
        types[3]:StaticDispatcher
        types[4]:AdvisedDispatcher
        types[5]:EqualsInterceptor
        types[6]:HashCodeInterceptor
下面我们来分析CglibAopProxy的 accept 方法

CglibAopProxy.java

public int accept(Method method) {
    if (AopUtils.isFinalizeMethod(method)) {
        logger.debug("Found finalize() method - using NO_OVERRIDE");
        //如果方法名为finalize,并且方法参数个数为0,则使用SerializableNoOp拦截器
        return 2;			
    }
   
    // opaque :该属性用于空值生成的代理对象是否可以强制转型为Advised,默认值为false,
    // 表示任何生成的代理对象都可以强制转换成Advised,true是不可以,可以通过Adviced查询代理对象的一些状态
    if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Method is declared on Advised interface: " + method);
        }
        //如果opaque属性为 false,任何生成的代理对象都可以强制转换成Advised,
        //并且该方法所在类是一个接口,并且该方法所在类是 Advised 子孙类,将使用AdvisedDispatcher转发器
        return 4;
    }
    if (AopUtils.isEqualsMethod(method)) {
        logger.debug("Found 'equals' method: " + method);
        //如果方法是equals方法,并且参数个数是1,并且第一个参数是 Object 类型,将使用EqualsInterceptor拦截器
        return 5;
    }
    if (AopUtils.isHashCodeMethod(method)) {
        logger.debug("Found 'hashCode' method: " + method);
        //如果方法名是hashCode,并且方法参数个数为0,则使用HashCodeInterceptor拦截器
        return 6;
    }
    Class<?> targetClass = this.advised.getTargetClass();
    //获取方法的拦截器链,这个方法特别重要,是 aop 方法拦截的关键
    List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    //如果拦截器链不为空
    boolean haveAdvice = !chain.isEmpty();
    //如果用户配置了expose-proxy="true",强制使用动态代理 ,比如 AService中有方法 a和b,在 a方法里调用 b方法,
    默认情况下,是不会对 b 方法拦截的,但是配置了expose-proxy="true",将会对 b方法实现拦截 
    boolean exposeProxy = this.advised.isExposeProxy();
    //如果是单例的话,默认为 true 
    boolean isStatic = this.advised.getTargetSource().isStatic();
    // 标记该配置是否需要被冻结,如果被冻结,将不可以修改增强的配置。
	// 如果该值为true,那么代理对象的生成的各项信息配置完成,则不容许更改,如果ProxyFactory设置完毕,该值为true,
	// 则不能对Advice进行改动,可以优化代理对象生成的性能。默认情况下该值为false 
    boolean isFrozen = this.advised.isFrozen();
    //如果拦截器链中有 advisor 或者可以对代理对象生成的各项信息配置进行更改
    if (haveAdvice || !isFrozen) {
        if (exposeProxy) {
            if (logger.isDebugEnabled()) {
                logger.debug("Must expose proxy on advised method: " + method);
            }
            //如果expose-proxy="true",直接使用DynamicAdvisedInterceptor
            return 0;
        }
        String key = method.toString();
        //如果是单例,并且是不可以对各项配置信息修改,而且固定拦截器中还有该方法的名称,从固定拦截器集合中获取拦截器
        if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method has advice and optimisations are enabled: " + method);
            }
            int index = this.fixedInterceptorMap.get(key);
            return (index + this.fixedInterceptorOffset);
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to apply any optimisations to advised method: " + method);
            }
            //还是使用DynamicAdvisedInterceptor拦截
            return 0;
        }
    }
    else {

        if (exposeProxy || !isStatic) {
        	//如果expose-proxy="true",并且不是静态的,使用StaticUnadvisedExposedInterceptor拦截器
            return 1;
        }
        Class<?> returnType = method.getReturnType();
        if (targetClass == returnType) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        "has return type same as target type (may return this) - using INVOKE_TARGET");
            }
            //方法的返回值类型和目标值类型相同,则使用StaticUnadvisedExposedInterceptor拦截器
            return 1;
        }
        else if (returnType.isPrimitive() || !returnType.isAssignableFrom(targetClass)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        " has return type that ensures this cannot be returned- using DISPATCH_TARGET");
            }
            //如果返回值类型是boolean,character,byte,short,int,long,Float,Double,Void 类型,并且目标值类型不是返回值类型的子孙类 
            //则使用StaticDispatcher
            return 3;
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        "has return type that is assignable from the target type (may return this) - " +
                        "using INVOKE_TARGET");
            }
            //如果是其他情况将使用StaticUnadvisedExposedInterceptor拦截器
            return 1;
        }
    }
}

AdvisedSupport.java

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    List<Object> cached = this.methodCache.get(cacheKey);
    if (cached == null) {
    	//获取当前方法的拦截器链
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                this, method, targetClass);
        this.methodCache.put(cacheKey, cached);
    }
    return cached;
}

DefaultAdvisorChainFactory.java

@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
        Advised config, Method method, Class<?> targetClass) {
    
    List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
    Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    //当前类是否匹配引介增强
    boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

    for (Advisor advisor : config.getAdvisors()) {
        if (advisor instanceof PointcutAdvisor) {
            //如果当前 advisor是 PointcutAdvisor
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            //下面的这个是快速匹配,查看当前类和切点表达式是否匹配,如果不匹配,则略过
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            	// 获取当前通知器的方法拦截器,如果没有配置@Before,@AfterReturning,@AfterThrowing注解的,
            	// Advisor 即是拦截器本身,如果是配置了这些注解的,将用new MethodBeforeAdviceInterceptor(advice),
            	// new AfterReturningAdviceInterceptor(advice),new ThrowsAdviceInterceptor(advisor.getAdvice())包装一下
                MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                //切点表达式与方法精确匹配
                if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                	//这个方法有点意思,也就是判断当前切点表达式解析出来的对象中是否有WithinAnnotationPointcut类型,
                	WithinCodeAnnotationPointcut,AnnotationPointcut,ArgsAnnotationPointcut,ArgsPointcut,
                	CflowPointcut,IfPointcut,NotAnnotationTypePattern,NotPointcut,ThisOrTargetAnnotationPointcut,
                	ThisOrTargetPointcut。
                	//这句话是什么意思呢?比如我们切点表达式是execution(* com..test65_2.*.*(..)) && args(x,y)
                	//在这个表达式args(x,y),而这个表达式最终会被解析成ArgsPointcut对象,而 Spring发现表达式解析出来的对象中有ArgsPointcut
                	//那么isRuntime就返回 true 了
                    if (mm.isRuntime()) {
                    	//将方法拦截器加入到拦截器链中
                        for (MethodInterceptor interceptor : interceptors) {
                            interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                        }
                    }
                    else {
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
            }
        }
        //如果通知器是引介增强
        else if (advisor instanceof IntroductionAdvisor) {
            IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
            if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }
        else {
        	//如果在其他切点类型,则从注册器中获取拦截器
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }
    return interceptorList;
}

到这里,我们终于解析完动态代理的创建过程,当代理创建完以后,方法拦截器链保存到了advised的methodCache中,那方法调用时,使用DynamicAdvisedInterceptor拦截器逐个调用拦截器链,那这个调用过程在下一篇博客中再来细细道来。

过程:

1)postProcessAfterInitialization():bean 的创建过程中,initializeBean()的后处理器
	1)wrapIfNecessary():早期代理引用中如果不包含当前 bean 的代理,则调用此方法。
		1)getAdvicesAndAdvisorsForBean():获取 bean 的通知器
			1)findEligibleAdvisors():发现当前bean 的通知器
				1)findCandidateAdvisors():发现系统所有的 Advisor
					1)beanNamesForTypeIncludingAncestors(): 发现所有Advisor类型的 bean
					2)buildAspectJAdvisors():构建所有的isAspect的 Advisor
						1)getAdvisors(): 获取所有的 Advisor
							1)getAdvisor():获取 advisor 
								1)getPointcut():获取切点 
									1)findAspectJAnnotationOnMethod(): 发现切面注解
									2)new AspectJExpressionPointcut():构建切点表达式对象
								2)new InstantiationModelAwarePointcutAdvisorImpl(): 创建 advisor
									1)instantiateAdvice():初始化 advice
										1)getAdvice(): 从工厂方法中获取 Advice 
											1)new AspectJMethodBeforeAdvice():如果方法配置了@Before 注解
											2)new AspectJAfterAdvice(): 如果方法配置了@After 注解
											3)new AspectJAfterReturningAdvice(): 如果方法配置了@AfterReturning注解
												1)setReturningName():设置返回值名称
											4)new AspectJAfterThrowingAdvice(): 如果配置了@AfterThrowing注解
												1)setThrowingName():设置异常属性名
											5)new AspectJAroundAdvice(): 如果配置了@Around注解
											6)calculateArgumentBindings(): 绑定方法参数名和参数类型
				2) findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz):发现匹配当前类方法的 Advisor
					1)canApply(): 判断 Advisor是否和当前类匹配
						1)matches(): 匹配成功,返回 TRUE,将当前 Advisor 加入到匹配列表中
				3) extendAdvisors():
					1)makeAdvisorChainAspectJCapableIfNecessary(): 创建通知器链
						1) new ExposeInvocationInterceptor(): 将ExposeInvocationInterceptor的 Advisor 加入到advisors中
				4)sortAdvisors():对 Advisors 排序。
		2)createProxy():创建代理 
			1) buildAdvisors(beanName, specificInterceptors):通过 bean 名称和拦截器构建Advisor
				1) resolveInterceptorNames(): 获取系统定义的拦截器
				2)addAll() : 将系统拦截器和用户自定义拦截器合并
			2) createAopProxy(): 创建 aop 代理 
				1)getAopProxyFactory():获取代理工厂
					1)JdkDynamicAopProxy() : 创建 jdk 代理
					2)ObjenesisCglibAopProxy(): 创建 cglib 代理 ,如没有接口,直接创建 Cglib 代理
				2)createAopProxy():创建代理
					1)getProxy():获取代理
						1)getTargetClass():获取目标类
						2)createEnhancer():创建 Enhancer
						3)createProxyClassAndInstance():创建代理实例
							1)createClass():创建代理类
								1)accept(Method method): 代理回调
									1)getInterceptorsAndDynamicInterceptionAdvice(): 获取拦截器链
										1)matches():如果目标方法和 Advisor切面表达式匹配,则加入到目标方法的调用链中
							2)newInstance(): 创建实例
							

我们经过上面的分析,Spring在创建代理的过程,写了大量的代码。但是理清思路后,发现还是简单的。

    Spring 遍历所有的 bean,找到配置了@Aspect 注解的类从配置了@Aspect 注解的类中拿到所有配置了@Around …@Before 注解的方法,并封装成相应的 Advisor遍历目标类的所有方法,与 Advisor 逐一进行匹配,如果匹配成功,创建动态代理 。

到这里,我们己经对于bean 的创建己经分析完成,如果目标类中有方法和 Advisor匹配,则创建动态代理 ,存储于容器中。最终,通过 getBean 得到的是代理类,代理是如何逐一调用各个通知器的,在下一篇博客中再来分析 。

思考?

Aservice.java

public interface Aservice  {
    void b (String x,String y);
}

AserviceImpl.java

@Service
public class AserviceImpl implements Aservice {
    @Override
    public void b(String x,String y ) {
        System.out.println("print x=" + x + ",y="+y);
    }
}

AspectJTest.java

@Aspect
public class AspectJTest {

    @Pointcut("execution(* com.spring_1_100.test_61_70.test65.*.*(..)) && args(..)")
    public void test() {

    }

    @Before("test()")
    public void abeforeTest(JoinPoint jp) {
        System.out.println("abeforeTest" + JSON.toJSONString(jp.getArgs()));
    }


    @Before("test()")
    public void beforeTest() {
        System.out.println("beforeTest");
    }


    @After("test()")
    public void afterTest() {
        System.out.println("afterTest()");
    }


    @After("test()")
    public void bafterTest() {
        System.out.println("bafterTest()");
    }


    @AfterReturning("test()")
    public void AfterReturning() {
        System.out.println("AfterReturning()");
    }

    @AfterThrowing(pointcut = "test()", throwing = "e")
    public void afterThrowing(Exception e) {
        System.out.println("例外通知");
        System.out.println(e.getMessage());
    }

    @Around("test()")
    public Object aroundTest(ProceedingJoinPoint p) {
        System.out.println("around before1");
        Object o = null;
        try {
            o = p.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("around after1");
        return o;
    }

}

spring65.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">


    <aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>
    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="com.spring_1_100.test_61_70.test65"></context:component-scan>

    <bean id="aservice" class="com.spring_1_100.test_61_70.test65.AserviceImpl"></bean>
    <bean class="com.spring_1_100.test_61_70.test65.AspectJTest"></bean>

</beans>

测试:

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_61_70/spring65.xml");
    Aservice service =(Aservice) ac.getBean("aservice");
    service.b("quyixiao","hukaiming");
}

结果是什么?为什么?

本文的github地址是
https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_101_200/test_111_120/test_117_excution/excution1

匿名

发表评论

匿名网友