Spring源碼解析之基於註解的SpringAOP源碼解析(一)

準備工作


Spring源碼解析之基於註解的SpringAOP源碼解析(一)


本文分析Spring的AOP模塊的整體流程,分析過程需要使用一個簡單的demo工程來啟動Spring。

<code>https://github.com/cjinjun/spring-framework-demo/<code>

寫一個簡單的接口和實現類,跟IOC源碼解析那幾篇文章用的同一個工程,

<code>public interface IOCService {
public String helloIoc();
}

public class IOCServiceImpl implements IOCService {
public String helloIoc() {
return "Hello,IOC";
}
}/<code>

增加bean的配置類,以及啟動AOP

<code>@EnableAspectJAutoProxy
@Configuration
public class AnnotationConfig {
@Bean
public IOCService iocService(){
return new IOCServiceImpl();
}
}/<code>

創建切點

<code>@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;
}
}/<code>

啟動spring

<code>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註解());
}
}/<code>

代碼部分到此,然後首先看一下

@EnableAspectJAutoProxy註解

為了開啟AOP功能,使用了一個@EnableAspectJAutoProxy註解,進入這個註解可以查看到這個註解的2個屬性,相信大家都已經很熟悉了,就不相信的說明了。除此之外可以看到這個註解使用@Import註解引入了一個配置類

@Import註解:可以引入一個類,將這個類注入到Spring IOC容器中被當前Spring管理

<code>@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//proxyTargetClass屬性,默認false,嘗試採用JDK動態代理織入增強(如果當前類沒有實現接口則還是會使用CGLIB);如果設為true,則強制採用CGLIB動態代理織入增強
boolean proxyTargetClass() default false;
//通過aop框架暴露該代理對象,aopContext能夠訪問。為了解決類內部方法之間調用時無法增強的問題
boolean exposeProxy() default false;
}/<code>

看一下這個配置類的操作

<code>
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//註冊一個AOP代理實現的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);
}
}

}
}/<code>

registerAspectJAnnotationAutoProxyCreatorIfNecessary方法的主要功能是註冊或者升級AnnotationAwareAspectJAutoProxyCreator類,這個類在AOP中非常的重要,它的主要功能就是根據@Point註解定義的切點來自動代理與表達式匹配的類。下面看一個這個實現的邏輯

<code>private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //如果已存在這個bean
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
//判斷優先級,如果優先級較高則替換原先的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 {
//註冊AnnotationAwareAspectJAutoProxyCreator到容器中,此類負責基於註解的AOP動態代理實現
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;
}
}/<code>

註冊的AnnotationAwareAspectJAutoProxyCreator這個類間接實現了BeanPostProcessor接口。還記得我們之前在對SpringIOC的源碼進行解析時提到過,Spring在實例化Bean的前後會分別調用方法postProcessBeforeInstantiation和postProcessAfterInstantiation而AOP的整體邏輯就是通過這兩個方法來實現的

postProcessBeforeInstantiation

首先看一下這個postProcessBeforeInstantiation方法,它是在bean實例化之前調用的,主要是針對切面類。這個方法不在AnnotationAwareAspectJAutoProxyCreator這個類中,而是在其父類AbstractAutoProxyCreator中

<code>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;
}
//加載所有增強
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;
}/<code>

加載增強

上方代碼中最重要的一個方法就是shouldSkip方法了,被AspectJAwareAdvisorAutoProxyCreator所重載

<code>
protected boolean shouldSkip(Class> beanClass, String beanName) {

//查找所有標識了@Aspect註解的類,這裡是重點,接著往下看
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是重點
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}/<advisor>/<advisor>/<advisor>/<advisor>/<code>
<code>
public List<advisor> buildAspectJAdvisors() {
//所有Aspect類的名稱集合
List<string> aspectNames = this.aspectBeanNames;
if (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) {
//判斷是否符合條件,比如說有時會排除一些類,不讓這些類注入進Spring
if (!isEligibleBean(beanName)) {
continue;
}

Class> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//判斷Bean的Class上是否標識@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);
//下一步說,重點的重點
List<advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
//將解析的Bean名稱及類上的增強緩存起來,每個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) {
//從緩存中獲取當前Bean的切面實例,如果不為空,則指明當前Bean的Class標識了@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;
}/<advisor>/<advisor>/<advisor>/<advisor>/<string>/<advisor>/<advisor>/<string>/<advisor>/<code>

生成增強

advisorFactory.getAdvisors方法會從@Aspect標識的類上獲取@Before,@Pointcut等註解的信息及其標識的方法的信息,生成增強

<code>public List<advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校驗類的合法性相關
validate(aspectClass);

MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

List<advisor> advisors = new LinkedList<advisor>();
//獲取這個類所有的增強方法
for (Method method : getAdvisorMethods(aspectClass)) {
//生成增強實例
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標識的類內部排除@Pointcut標識之外的所有方法,得到的方法集合包括繼承自父類的方法,包括繼承自Object的方法
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
//對得到的所有方法排序,
//如果方法標識了切面註解,則按@Around, @Before, @After, @AfterReturning, @AfterThrowing的順序排序
//如果沒有標識這些註解,則按方法名稱的字符串排序,
//有註解的方法排在無註解的方法之前
//最後的排序應該是這樣的Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class。。。
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}/<method>/<method>/<method>/<advisor>/<advisor>/<advisor>/<code>

調用生成增強實例的方法

<code>public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//再次校驗類的合法性
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切點表達式的包裝類裡面包含這些東西:execution(public * cn.shiyujun.service.IOCService.hollo(..))
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//根據方法、切點、AOP實例工廠、類名、序號生成切面實例,詳細代碼往下看

return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class> candidateAspectClass) {
//查詢方法上的切面註解,根據註解生成相應類型的AspectJAnnotation,在調用AspectJAnnotation的構造函數的同時
//根據註解value或pointcut屬性得到切點表達式,有argNames則設置參數名稱
AspectJAnnotation> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//過濾那些不含@Before, @Around, @After, @AfterReturning, @AfterThrowing註解的方法
if (aspectJAnnotation == null) {
return null;
}
//生成帶表達式的切面切入點,設置其切入點表達式
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}/<code>

InstantiationModelAwarePointcutAdvisorImpl的構造方法

<code>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;
//重點在這裡
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);
}/<code>

生產增強

<code>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();
//又是一次校驗
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;
//根據註解類型生成不同的通知實例

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);
}

//設置通知方法所屬的類
springAdvice.setAspectName(aspectName);
//設置通知的序號,同一個類中有多個切面註解標識的方法時,按上方說的排序規則來排序,
//其序號就是此方法在列表中的序號,第一個就是0
springAdvice.setDeclarationOrder(declarationOrder);

//獲取通知方法的所有參數
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
//將通知方法上的參數設置到通知中
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//計算參數綁定工作,此方法詳解請接著往下看
springAdvice.calculateArgumentBindings();
return springAdvice;
}
}/<code>

校驗方法參數並綁定

<code>public synchronized final void calculateArgumentBindings() {
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
}

int numUnboundArgs = this.parameterTypes.length;
Class>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
//切面註解標識的方法第一個參數要求是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) { //獲取方法參數的名稱
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) {
//此屬性用來存儲方法未綁定的參數名稱,及參數的序號
this.argumentBindings = new HashMap<string>();

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代表第一個未綁定參數的順序
int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
//存儲未綁定的參數名稱及其順序的映射關係
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 有值,驗證,解析,同時得到定義返回值的類型
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 有值,驗證,解析,同時得到拋出異常的類型
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++;
}
//剩餘的未綁定的參數會賦值給AspectJExpressionPointcut(表達式形式的切入點)的屬性,以備後續使用
this.pointcut.setParameterNames(pointcutParameterNames);
this.pointcut.setParameterTypes(pointcutParameterTypes);
}/<string>/<code>

篇幅原因,本文到此結束,期待下集,下集主要說明postProcessAfterInitialization 及Aop 剩下的實現邏輯


分享到:


相關文章: