Spring AOP源码分析(二)

1,861 阅读11分钟

1.Spring AOP源码分析(二)

无论是单例Bean还是原型Bean,对于AOP的实现其实就是依赖于BeanPostProcessor的回调,这里主要有个主要的实现类:SmartInstantiationAwareBeanPostProcessor,这个类即实现了BeanPostProcessor,也实现了InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor提供了一个postProcessorBeforeInstantiation方法,BeanPostProcessor提供了一个postProcessorAfterInitialization方法。

上面的类图可以看出来入口就是AbstractAutoProxyCreator

1.AbstractAutoProxyCreator#postProcessBeforeInstantiation

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation在IOC实例化Bean之前会调用org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    //3.通过BeanPostProcessor返回代理Bean
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
        return bean;
    }
    
    //4.常规创建bean
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
}

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    Object cacheKey = getCacheKey(beanClass, beanName);

    //1.不需要创建代理
    if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        //2.如果是基础设施或者应该跳过的类,则说明这个类不需要创建代理,缓存起来
        //默认shouldSkip是false,都不应该跳过
        //但是AspectJAwareAdvisorAutoProxyCreator实现了该方法
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    //2.对于自定义的TargetSource会立即创建代理,并缓存
    if (beanName != null) {
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        //如果不是TargetSource,一般不会走到这里
        if (targetSource != null) {
            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;
}

这个方法是在Bean Instance之前,判断当前这个Bean是否需要生成代理,如果是AOP的基础设施类或者应该跳过的类,则不生成代理;如果是自定义的targetSource,则立即生成代理。

因为AspectJAwareAdvisorAutoProxyCreator实现了shouldSkip方法,而且AspectJAwareAdvisorAutoProxyCreator是由<aop:config/>转换而来,也就是针对XML的,那也可以说注解方式都不跳过。

shouldSkip默认是false,即所有的Bean都不跳过,现在看下AspectJAwareAutoProxyCreator的实现:

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    //1.获取所有的Advisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        //对于<aop:aspect/>中的<aop:before/>类似的生成的是AspectJPointcutAdvisor
        //Advice就是AbstractAspectJAdvice的子类
        if (advisor instanceof AspectJPointcutAdvisor) {
            if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
                return true;
            }
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

这个方法获取IOC容器中所有的候选切面,如果advisorAspectJPointcutAdvisor并且advice是当前类,则返回true,应该跳过,否则调用父类的方式,返回false,不跳过。

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

protected List<Advisor> findCandidateAdvisors() {
    //调用一个工具类
    return this.advisorRetrievalHelper.findAdvisorBeans();
}

org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans

public List<Advisor> findAdvisorBeans() {
    //1.缓存的通知器的名称
    String[] advisorNames = this.cachedAdvisorBeanNames;
    //2.如果cachedAdvisorBeanNames为空,则到容器中查找
    //并设置缓存,后续直接使用缓存即可
    if (advisorNames == null) {
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    if (advisorNames.length == 0) {
        return new ArrayList<Advisor>();
    }

    List<Advisor> advisors = new ArrayList<Advisor>();
    //3.遍历所有的通知器
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
            //4.忽略正在创建的advisor
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipping currently created advisor '" + name + "'");
                }
            }
            else {
                //5.从容器中获取Advisor,并添加到advisors中,在这个时候Advisor就被实例化了
                advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
        }
    }
    return advisors;
}

通过一个帮助类BeanFactoryAdvisorRetrievalHelper来获取Advisor,首先从缓存中获取advisorNames,如果不存在则根据类型获取advisorNames并放入缓存,然后通过遍历advisorNames,从容器中获取bean,当然这里如果要获取的bean还未被实例化,则会进行实例化,最后返回所有的Advisor。这里会忽略FactoryBean和正在创建的Advisor

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getCustomTargetSource

protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
    if (this.customTargetSourceCreators != null &&
        this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
        for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
            TargetSource ts = tsc.getTargetSource(beanClass, beanName);
            if (ts != null) {
                return ts;
            }
        }
    }
    return null;
}

从容器中获取自定义的TargetSource,一般默认都是使用SingletonTargetSource

如果不需要跳过,则根据自定义的TargetSource立即创建代理,TargetSource被用来执行MethodInvocation的时候获取真正的target。所以,proxy代理的并不是target,而是targetSource

通常情况下,一个代理对象只能代理一个target,每次调用目标方法也是唯一的target。但是如果让proxy代理targetSource,可以是的每次调用的target实例都不同。当然这取决于targetSource的实现,这种机制,使得方法的调用更加灵活。

1.查找通知

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected abstract Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, TargetSource customTargetSource) throws BeansException;

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
    //1.查找合适的通知器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

获取合适的通知器。

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //1.查找所有的通知器
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //2.筛选可以在该bean上应用的通知器,通过ClassFilter和MethodMatcher对目标类和方法进行匹配
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    //3.扩展操作
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

获取合适的通知器,主要分为3步:1.查找所有的通知;2.过滤通知;3.扩展通知。

获取通知主要有两种方式:1.基于XML;2.基于注解。

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors这个方法在shouldSkip的时候已经执行过了,就是根据所有的advisorNames获取所有的Advisor,因为shouldSkip的时候已经创建过了advisor bean,所以这里getBean的时候可以直接拿到。

对于注解的,其实就是多调用了一个方法从容器中获取被@Aspect注解的类。

@Override
protected List<Advisor> findCandidateAdvisors() {
    //1.调用父类方法查找所有的通知
    List<Advisor> advisors = super.findCandidateAdvisors();
    //2.解析@Aspect注解,并构建通知
    advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    return advisors;
}

在调用AspectJAwareAdvisorAutoProxyCreator#findCandidateAdvisors获取所有xml的之后,获取被@Aspect注解的类,并转为Advisor

从这个结果可以看出来是使用AspectJPonitcutAdvisor,其内部包含了AdvicePointcutOrder,也就意味着现在拿到了整个应用程序中所有的切面。

2.过滤通知

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

protected List<Advisor> findAdvisorsThatCanApply(
    List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        //调用重载方法
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

通过一个线程单例进行过滤符合当前Bean的切面。

org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

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) {
        //1.筛选IntroductionAdvisor的通知器
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // already processed
            continue;
        }
        //2.筛选普通类型通知器
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

org.springframework.aop.support.AopUtils#canApply

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    if (advisor instanceof IntroductionAdvisor) {
        //1.从通知器中获取ClassFilter,并调用matches进行匹配
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    else if (advisor instanceof PointcutAdvisor) {
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        //2.对于普通Advisor,这里继续调用重载方法进行筛选
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
    else {
        return true;
    }
}

org.springframework.aop.support.AopUtils#canApply

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		//1.使用ClassFilter匹配Class
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		//2.查找当前类及其父类的所有Class,只要有一个方法符合,就说明该切面是适用于当前bean的
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
			//3.获取当前类的方法列表,包括从父类继承而来的
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				//4.使用methodMatcher匹配方法,匹配成功立即返回
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

上述源码表示了按照切点(Pointcut)对切面(Advisor)的过滤的一个过程,这里有两个重要的类:1.ClassFilter;2.MethodMatcherClassFilter用于根据切点过滤类,MethodMatcher用于根据切点过滤类的方法,只要某个类中的某个方法符合,那么就说明该切面适用于该Bean

3.通知扩展

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#extendAdvisors

protected void extendAdvisors(List<Advisor> candidateAdvisors) {
}

默认是一个空实现,交由子类实现。

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#extendAdvisors

/**
* 将{@link ExposeInvocationInterceptor}添加到通知责任链的开头
* 当使用AspectJ表达式切点和AspectJ样式的通知的时候,这是必须的
*/
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
    AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary

/**
* 增加特定的通知器到通知责任链头部,如果责任链包含AspectJ通知器
* 如果不包含AspectJ通知器,则无效
* 目的是暴露当前AOP的调用链,确保JoinPoint可用
*/
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
    // Don't add advisors to an empty list; may indicate that proxying is just not required
    // 1.如果通知器列表是一个空列表,则啥都不做
    if (!advisors.isEmpty()) {
        boolean foundAspectJAdvice = false;
        //2.用于检测advisors列表中是否存在AspectJ类型的Advisor或Advice
        for (Advisor advisor : advisors) {
            // Be careful not to get the Advice without a guard, as
            // this might eagerly instantiate a non-singleton AspectJ aspect
            if (isAspectJAdvice(advisor)) {
                foundAspectJAdvice = true;
            }
        }

        //3.向advisors列表的首部添加DefaultPointcutAdvisor
        if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
            advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
            return true;
        }
    }
    return false;
}

增加ExposeInvocationInterceptor这个拦截器为第一个执行的作用是使用一个线程单例保存了MethodInvocation,这个MethodInvocation其实就是执行通知和目标方法的对象,当有其他的地方需要这个MethodInvocation的时候,就可以通过ExposeInvocationInterceptor#currentInvocation获取。

4.创建代理

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

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

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    //1.默认情况下,proxy-target-class=false,使用jdk动态代理
    if (!proxyFactory.isProxyTargetClass()) {
        //判断proxy-target-class属性
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            //2.检查目标类是否实现了接口,如没有,则设置proxy-target-class=true,使用cglib动态代理
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    //3.确保所有的都是Advisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    //4.创建代理
    return proxyFactory.getProxy(getProxyClassLoader());
}

为目标对象创建代理类,首先需要判断proxy-target-class,这个属性已经看过很多次了,表达代理的方式,如果proxy-target-class为false,但是该类没有实现接口,那么也还是使用CGLIB代理;然后确保所有的拦截器都是Advisor;最后通过ProxyFactory创建代理类,并返回存在IOC容器中。

org.springframework.aop.framework.ProxyFactory#getProxy

public Object getProxy(ClassLoader classLoader) {
    //1.先创建AopProxy(DefaultAopProxyFactory会根据条件决定创建哪种AopProxy),然后再创建bean的代理
    return createAopProxy().getProxy(classLoader);
}

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    //1.是否需要优化||代理类型(前面已经设置过了)||是否实现了接口
    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.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        //2.使用cglib动态代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        //3.使用jdk动态代理
        return new JdkDynamicAopProxy(config);
    }
}

org.springframework.aop.framework.CglibAopProxy#getProxy

@Override
public Object getProxy(ClassLoader classLoader) {
    //1.从TargetSource获取target的class
    Class<?> rootClass = this.advised.getTargetClass();

    //2.判断是否已经是代理类了
    Class<?> proxySuperClass = rootClass;
    if (ClassUtils.isCglibProxyClass(rootClass)) {
        proxySuperClass = rootClass.getSuperclass();
        Class<?>[] additionalInterfaces = rootClass.getInterfaces();
        for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
        }
    }

    //3.CGLIB
    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 ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

    //4.各种回调
    Callback[] callbacks = getCallbacks(rootClass);
    Class<?>[] types = new Class<?>[callbacks.length];
    for (int x = 0; x < types.length; x++) {
        types[x] = callbacks[x].getClass();
    }

    //5.回调过滤
    enhancer.setCallbackFilter(new ProxyCallbackFilter(
        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
    enhancer.setCallbackTypes(types);

    //6.创建代理实例
    return createProxyClassAndInstance(enhancer, callbacks);
}

org.springframework.aop.framework.JdkDynamicAopProxy#getProxy

@Override
public Object getProxy(ClassLoader classLoader) {
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

获取代理的两种方式:1.JDK;2.CGLIB。当执行AOP的时候,入口也是在这两个类。

2.AbstractAutoProxyCreator#postProcessAfterInitialization

Bean实例化完成之后,就要执行初始化方法了,这个会调用BeanPostProcessor的初始化回调方法,在这里才会真正的生成代理对象,上面的postProcessorBeforeInstantiation是在Bean实例化之前执行,而且一般不会在这个方法中生成代理对象,而是在该方法中。

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

/**
* bean初始化后置处理方法
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            //如果需要,为bean生成代理对象
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

这就是AOP的入口,对于单例Bean会在预实例化的时候调用,拿到代理对象,并放入单例的缓存中;对于原型Bean,因为没有缓存,每一次调用Bean的时候都需要执行该方法判断是否需要生成代理对象。

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

/**
* 是否需要为目标类生成代理类
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    //1.这两个集合在postProcessorBeforeInitialization中生成的,这里可直接使用
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    //2.如果是基础设施类(Pointcut、Advice、Advisor等的实现类),或是应该跳过的类
    //则不应该生成代理类,直接返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    //3.为目标Bean查找合适的通知和通知器
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    //4.如果通知存在,则生成代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        //5.创建代理
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    //6.通知不存在,直接返回bean
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

可以看到这个真正生成代理对象的方法,也是相同的步骤,调用相同的方法:1.判断基础设施(shouldSkip);2.查找通知(getAdvicesAndAdvisorsForBean);3.创建代理(createProxy)。与上面完全是一模一样的。

总结一下:

1.获取通知。从IOC容器中获取所有的Advisor,如果不存在,则创建。

2.过滤通知。根据Pointcutexpression通过ClassFilterMethodMatcher进行过滤,找到可以应用AOP的类及方法。

3.扩展通知。通过ExposeInvocationInterceptor的线程单例暴露执行的MethodInvocation,以便其他地方使用。

4.创建代理对象。根据proxy-target-class选择JDK动态代理还是CGLIB动态代理,如果proxy-target-class为false,但是该类未实现接口,那么依然会使用CGLIB动态代理。