本文分析Spring的AOP模塊的整體流程袱院,分析過程需要使用一個(gè)簡單的demo工程來啟動(dòng)Spring嘁字。
https://github.com/cjinjun/spring-framework-demo
寫一個(gè)簡單的接口和實(shí)現(xiàn)類蒿往,跟IOC源碼解析那幾篇文章用的同一個(gè)工程劣欢,
public interface IOCService {
public String helloIoc();
}
public class IOCServiceImpl implements IOCService {
public String helloIoc() {
return "Hello,IOC";
}
}
增加bean的配置類棕诵,以及啟動(dòng)AOP
@EnableAspectJAutoProxy
@Configuration
public class AnnotationConfig {
@Bean
public IOCService iocService(){
return new IOCServiceImpl();
}
}
創(chuàng)建切點(diǎn)
@Aspect
@Component
public class AspectJTest {
@Pointcut("execution(public * com.jinjun.demo.ioc.service..IOCService.helloIoc(..))")
public void testAOP(){}
@Before("testAOP()")
public void before(){
System.out.println("before AOP...");
}
@After("testAOP()")
public void after(){
System.out.println("after AOP...");
}
@Around("testAOP()")
public Object around(ProceedingJoinPoint p){
System.out.println("around before AOP...");
Object o = null;
try {
o = p.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("around after AOP...");
return o;
}
}
啟動(dòng)spring
public class AnnotationIOCDemo {
public static void main (String args[]){
ApplicationContext context = new AnnotationConfigApplicationContext("cn.shiyujun.config");
IOCService iocService=context.getBean(IOCService.class);
System.out.println(iocService.@EnableAspectJAutoProxy注解());
}
}
代碼部分到此裁良,然后首先看一下
@EnableAspectJAutoProxy注解
為了開啟AOP功能,使用了一個(gè)@EnableAspectJAutoProxy注解校套,進(jìn)入這個(gè)注解可以查看到這個(gè)注解的2個(gè)屬性价脾,相信大家都已經(jīng)很熟悉了,就不相信的說明了笛匙。除此之外可以看到這個(gè)注解使用@Import注解引入了一個(gè)配置類
@Import注解:可以引入一個(gè)類侨把,將這個(gè)類注入到Spring IOC容器中被當(dāng)前Spring管理
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//proxyTargetClass屬性,默認(rèn)false妹孙,嘗試采用JDK動(dòng)態(tài)代理織入增強(qiáng)(如果當(dāng)前類沒有實(shí)現(xiàn)接口則還是會(huì)使用CGLIB)秋柄;如果設(shè)為true,則強(qiáng)制采用CGLIB動(dòng)態(tài)代理織入增強(qiáng)
boolean proxyTargetClass() default false;
//通過aop框架暴露該代理對(duì)象蠢正,aopContext能夠訪問骇笔。為了解決類內(nèi)部方法之間調(diào)用時(shí)無法增強(qiáng)的問題
boolean exposeProxy() default false;
}
看一下這個(gè)配置類的操作
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注冊(cè)一個(gè)AOP代理實(shí)現(xiàn)的Bean,往下看 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary方法的主要功能是注冊(cè)或者升級(jí)AnnotationAwareAspectJAutoProxyCreator類机隙,這個(gè)類在AOP中非常的重要蜘拉,它的主要功能就是根據(jù)@Point注解定義的切點(diǎn)來自動(dòng)代理與表達(dá)式匹配的類。下面看一個(gè)這個(gè)實(shí)現(xiàn)的邏輯
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //如果已存在這個(gè)bean
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
//判斷優(yōu)先級(jí)有鹿,如果優(yōu)先級(jí)較高則替換原先的bean
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
//注冊(cè)AnnotationAwareAspectJAutoProxyCreator到容器中旭旭,此類負(fù)責(zé)基于注解的AOP動(dòng)態(tài)代理實(shí)現(xiàn)
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
注冊(cè)的AnnotationAwareAspectJAutoProxyCreator這個(gè)類間接實(shí)現(xiàn)了BeanPostProcessor接口。還記得我們之前在對(duì)SpringIOC的源碼進(jìn)行解析時(shí)提到過葱跋,Spring在實(shí)例化Bean的前后會(huì)分別調(diào)用方法postProcessBeforeInstantiation和postProcessAfterInstantiation而AOP的整體邏輯就是通過這兩個(gè)方法來實(shí)現(xiàn)的
postProcessBeforeInstantiation
首先看一下這個(gè)postProcessBeforeInstantiation方法持寄,它是在bean實(shí)例化之前調(diào)用的,主要是針對(duì)切面類娱俺。這個(gè)方法不在AnnotationAwareAspectJAutoProxyCreator這個(gè)類中稍味,而是在其父類AbstractAutoProxyCreator中
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//加載所有增強(qiáng)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
加載增強(qiáng)
上方代碼中最重要的一個(gè)方法就是shouldSkip方法了,被AspectJAwareAdvisorAutoProxyCreator所重載
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
//查找所有標(biāo)識(shí)了@Aspect注解的類荠卷,這里是重點(diǎn)模庐,接著往下看
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
//buildAspectJAdvisors是重點(diǎn)
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
public List<Advisor> buildAspectJAdvisors() {
//所有Aspect類的名稱集合
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
//這個(gè)雙重檢查是不是在學(xué)習(xí)安全的單例模式的時(shí)候見過
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) {
//判斷是否符合條件,比如說有時(shí)會(huì)排除一些類油宜,不讓這些類注入進(jìn)Spring
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//判斷Bean的Class上是否標(biāo)識(shí)@Aspect注解
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);
//下一步說掂碱,重點(diǎn)的重點(diǎn)
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
//將解析的Bean名稱及類上的增強(qiáng)緩存起來,每個(gè)Bean只解析一次
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
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) {
//從緩存中獲取當(dāng)前Bean的切面實(shí)例,如果不為空慎冤,則指明當(dāng)前Bean的Class標(biāo)識(shí)了@Aspect疼燥,且有切面方法
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
生成增強(qiáng)
advisorFactory.getAdvisors方法會(huì)從@Aspect標(biāo)識(shí)的類上獲取@Before,@Pointcut等注解的信息及其標(biāo)識(shí)的方法的信息蚁堤,生成增強(qiáng)
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校驗(yàn)類的合法性相關(guān)
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<Advisor>();
//獲取這個(gè)類所有的增強(qiáng)方法
for (Method method : getAdvisorMethods(aspectClass)) {
//生成增強(qiáng)實(shí)例
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
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 {
//在@Aspect標(biāo)識(shí)的類內(nèi)部排除@Pointcut標(biāo)識(shí)之外的所有方法醉者,得到的方法集合包括繼承自父類的方法,包括繼承自O(shè)bject的方法
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
//對(duì)得到的所有方法排序,
//如果方法標(biāo)識(shí)了切面注解撬即,則按@Around, @Before, @After, @AfterReturning, @AfterThrowing的順序排序
//如果沒有標(biāo)識(shí)這些注解立磁,則按方法名稱的字符串排序,
//有注解的方法排在無注解的方法之前
//最后的排序應(yīng)該是這樣的Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class。搞莺。息罗。
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}
調(diào)用生成增強(qiáng)實(shí)例的方法
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//再次校驗(yàn)類的合法性
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切點(diǎn)表達(dá)式的包裝類里面包含這些東西:execution(public * cn.shiyujun.service.IOCService.hollo(..))
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//根據(jù)方法、切點(diǎn)才沧、AOP實(shí)例工廠迈喉、類名、序號(hào)生成切面實(shí)例温圆,詳細(xì)代碼往下看
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//查詢方法上的切面注解挨摸,根據(jù)注解生成相應(yīng)類型的AspectJAnnotation,在調(diào)用AspectJAnnotation的構(gòu)造函數(shù)的同時(shí)
//根據(jù)注解value或pointcut屬性得到切點(diǎn)表達(dá)式,有argNames則設(shè)置參數(shù)名稱
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//過濾那些不含@Before, @Around, @After, @AfterReturning, @AfterThrowing注解的方法
if (aspectJAnnotation == null) {
return null;
}
//生成帶表達(dá)式的切面切入點(diǎn)岁歉,設(shè)置其切入點(diǎn)表達(dá)式
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}
InstantiationModelAwarePointcutAdvisorImpl的構(gòu)造方法
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
this.pointcut = this.declaredPointcut;
this.lazy = false;
//重點(diǎn)在這里
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
//再往下看
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
生產(chǎn)增強(qiáng)
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//又是一次校驗(yàn)
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
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;
//根據(jù)注解類型生成不同的通知實(shí)例
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
//設(shè)置通知方法所屬的類
springAdvice.setAspectName(aspectName);
//設(shè)置通知的序號(hào),同一個(gè)類中有多個(gè)切面注解標(biāo)識(shí)的方法時(shí),按上方說的排序規(guī)則來排序忽媒,
//其序號(hào)就是此方法在列表中的序號(hào)蟹漓,第一個(gè)就是0
springAdvice.setDeclarationOrder(declarationOrder);
//獲取通知方法的所有參數(shù)
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
//將通知方法上的參數(shù)設(shè)置到通知中
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//計(jì)算參數(shù)綁定工作,此方法詳解請(qǐng)接著往下看
springAdvice.calculateArgumentBindings();
return springAdvice;
}
}
校驗(yàn)方法參數(shù)并綁定
public synchronized final void calculateArgumentBindings() {
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
}
int numUnboundArgs = this.parameterTypes.length;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
//切面注解標(biāo)識(shí)的方法第一個(gè)參數(shù)要求是JoinPoint,或StaticPart,若是@Around注解則也可以是ProceedingJoinPoint
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
if (numUnboundArgs > 0) {
//綁定屬性
bindArgumentsByName(numUnboundArgs);
}
this.argumentsIntrospected = true;
}
private void bindArgumentsByName(int numArgumentsExpectingToBind) {
if (this.argumentNames == null) { //獲取方法參數(shù)的名稱
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.");
}
}
private void bindExplicitArguments(int numArgumentsLeftToBind) {
//此屬性用來存儲(chǔ)方法未綁定的參數(shù)名稱万牺,及參數(shù)的序號(hào)
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.");
}
// So we match in number...,argumentIndexOffset代表第一個(gè)未綁定參數(shù)的順序
int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
//存儲(chǔ)未綁定的參數(shù)名稱及其順序的映射關(guān)系
this.argumentBindings.put(this.argumentNames[i], i);
}
// Check that returning and throwing were in the argument names list if
// specified, and find the discovered argument types.
//如果是@AfterReturning注解的returningName 有值蛛碌,驗(yàn)證寥殖,解析宙暇,同時(shí)得到定義返回值的類型
if (this.returningName != null) {
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];
}
}
//如果是@AfterThrowing注解的throwingName 有值,驗(yàn)證备绽,解析券坞,同時(shí)得到拋出異常的類型
if (this.throwingName != null) {
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];
}
}
// configure the pointcut expression accordingly.
configurePointcutParameters(argumentIndexOffset);
}
private void configurePointcutParameters(int argumentIndexOffset) {
int numParametersToRemove = argumentIndexOffset;
if (this.returningName != null) {
numParametersToRemove++;
}
if (this.throwingName != null) {
numParametersToRemove++;
}
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++) {
if (i < argumentIndexOffset) {
continue;
}
if (this.argumentNames[i].equals(this.returningName) ||
this.argumentNames[i].equals(this.throwingName)) {
continue;
}
pointcutParameterNames[index] = this.argumentNames[i];
pointcutParameterTypes[index] = methodParameterTypes[i];
index++;
}
//剩余的未綁定的參數(shù)會(huì)賦值給AspectJExpressionPointcut(表達(dá)式形式的切入點(diǎn))的屬性,以備后續(xù)使用
this.pointcut.setParameterNames(pointcutParameterNames);
this.pointcut.setParameterTypes(pointcutParameterTypes);
}
篇幅原因肺素,本文到此結(jié)束恨锚,期待下集,下集主要說明postProcessAfterInitialization 及Aop 剩下的實(shí)現(xiàn)邏輯