转载

Spring AOP源码实现分步解析

最基本的使用,在创建了业务接口和实现类后,通过配置 <aop:config>....</aop:config> 标签来指定 <aop:pointcut<aop:advisor 。示例如下:

1.1.1 创建接口及实现类

接口:

public interface MockService {
    public String hello(String s);
}
复制代码

实现类:

public class MockServiceImpl implements MockService {
    @Override
    public String hello(String s) {
        System.out.println("execute hello");
        return s;
    }
}
复制代码

1.1.2 实现方法拦截

实现接口 org.aopalliance.intercept.MethodInterceptor

public class CustomInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("CustomInterceptor before");
        Object result = invocation.proceed();
        System.out.println("CustomInterceptor after");
        return result;
    }
}
复制代码

1.1.3 配置xml

创建 aop.xml ,放在resources目录下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
       default-lazy-init="false" default-autowire="byName">

    <!-- 实现来org.aopalliance.intercept.MethodInterceptor的拦截器 -->
    <bean id="customInterceptor" class="com.xxx.yyy.CustomInterceptor"/>

    <bean id="mockService" class="com.xxx.yyy.MockServiceImpl"/>

    <aop:config proxy-target-class="true">
        <aop:pointcut id="interceptorPointCuts" expression="execution(* com.xxx.yyy..*.*(..))"/>
        <aop:advisor advice-ref="customInterceptor" pointcut-ref="interceptorPointCuts"/>
    </aop:config>
</beans>
复制代码

1.1.4 运行

public class Main {

    public static void main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
        MockService mockService = (MockService) context.getBean("mockService");
        mockService.hello("mock");
    }
}
复制代码

返回:

CustomInterceptor before
execute hello
CustomInterceptor after
复制代码

1.2 AOP实现过程

Spring环境启动过程中,会调用 AbstractApplicationContext.refresh() ,AOP的实现流程,也就是从这里开始。

  • 1 在 obtainFreshBeanFactory() 执行过程中,加载 aop.xml ,并根据 namespace 找到 aop 对应的 NamespaceHandlerAopNamespaceHandler
  • 2 AopNamespaceHandler 中,找到 config 标签对应的 BeanDefinitionParser 的实现对象,也就是 ConfigBeanDefinitionParser
  • 3 执行 ConfigBeanDefinitionParser.parse ,有两个作用:
    1. AspectJAwareAdvisorAutoProxyCreator 注册BeanDefinition;
    2. 解析 pointcutadvisor 等标签,并将相关对象注册为BeanDefinition。
  • 4 注册BeanPostProcessor: AspectJAwareAdvisorAutoProxyCreator 是BeanPostProcessor的实现类 AbstractAutoProxyCreator 的子类。注册BeanPostProcessor后, AspectJAwareAdvisorAutoProxyCreator 会在Spring创建bean的代理过程中调用。
  • 5 创建proxy,并用advisor增强,主要有几步:
    1. 创建代理;
    2. 查找匹配的advisor;
    3. 增强代理。

2 AopNamespaceHandler

Spring环境的加载,需要调用AbstractApplicationContext.refresh()。

在refresh()方法中,执行 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 创建BeanFacotry的时候,加载并解析xml资源。

在这个过程中,会调用 BeanDefinitionParserDelegate.parseCustomElement 进行扩展标签的解析:

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
                // 获取namespace
		String namespaceUri = getNamespaceURI(ele);
		// 根据文件META-INF/spring.handlers,获取对应的NamespaceHandler
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		// 调用NamespaceHandler.parse方法,返回BeanDefinition
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}

复制代码

详细过程可参考 Spring自定义标签配置的源码解析与实现 。

对于 <aop:config/> ,Spring会根据 xmlnsMETA-INF/spring.handlers 文件中查找相应的namespace解析类: http/://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

AopNamespaceHandler 中: registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());

所以:

  • aop namespace的解析类是 AopNamespaceHandler
  • <aop:config/> 标签的解析类是 ConfigBeanDefinitionParser ,在 ConfigBeanDefinitionParser 中, <aop:config/> 定义的各个元素被解析为 BeanDefinition

3 ConfigBeanDefinitionParser

ConfigBeanDefinitionParser 实现了 BeanDefinitionParser 接口,在 parse(Element element, ParserContext parserContext) 方法中,实现了两部分功能:

AspectJAwareAdvisorAutoProxyCreator
@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		CompositeComponentDefinition compositeDef =
				new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
		parserContext.pushContainingComponent(compositeDef);

        // 注册AspectJAwareAdvisorAutoProxyCreator为BeanDefinition
		configureAutoProxyCreator(parserContext, element);

		List<Element> childElts = DomUtils.getChildElements(element);
		for (Element elt: childElts) {
			String localName = parserContext.getDelegate().getLocalName(elt);
			if (POINTCUT.equals(localName)) {
			    // 解析pointcut
				parsePointcut(elt, parserContext);
			}
			else if (ADVISOR.equals(localName)) {
			    // 解析advisor
				parseAdvisor(elt, parserContext);
			}
			else if (ASPECT.equals(localName)) {
				parseAspect(elt, parserContext);
			}
		}

		parserContext.popAndRegisterContainingComponent();
		return null;
	}
复制代码

其中:

private static final String POINTCUT = "pointcut";
private static final String ADVISOR = "advisor";
private static final String ASPECT = "aspect";
复制代码

3.1 AspectJAwareAdvisorAutoProxyCreator

Spring AOP源码实现分步解析

3.1.1 作用

  • AspectJAwareAdvisorAutoProxyCreatorAbstractAutoProxyCreator 的子类;
  • AbstractAutoProxyCreator实现了接口 BeanPostProcessor ;
  • AbstractAutoProxyCreator在 postProcessAfterInitialization 的实现中,调用 wrapIfNecessary 进行bean代理。
@Override
	public Object postProcessAfterInitialization(@Nullable 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;
	}
复制代码

Spring在实例化bean的过程中,会调用 BeanPostProcessor 对bean生成前后进行处理,aop利用这一点:

调用AbstractAutoProxyCreator.postProcessAfterInitialization方法,根据pointcut查找到相应的advisor,对bean进行代理。

3.1.2 注册BeanDefinition

代码执行流程:

  • 1 ConfigBeanDefinitionParser.configureAutoProxyCreator;

  • 2 AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);

    public static void registerAspectJAutoProxyCreatorIfNecessary(
      		ParserContext parserContext, Element sourceElement) {
    
          // 注册BeanDefinition
      	BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
      			parserContext.getRegistry(), parserContext.extractSource(sourceElement));
      	// 设置class-proxy
      	useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
      	registerComponentIfNecessary(beanDefinition, parserContext);
      }
    复制代码
  • 3 AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary;

  • 4 AopConfigUtils.registerOrEscalateApcAsRequired:

public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
			"org.springframework.aop.config.internalAutoProxyCreator";
			
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		////  省略代码
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
复制代码

最终生成了 AspectJAwareAdvisorAutoProxyCreator 的BeanDefinition,beanName为 org.springframework.aop.config.internalAutoProxyCreator

同时, useClassProxyingIfNecessary 方法中,根据** aop:config/ **中的 proxy-target-class ,设置了AspectJAwareAdvisorAutoProxyCreator的一个父类 ProxyConfigproxyTargetClass 属性。

3.2 解析pointcut

解析 <aop:pointcut id="interceptorPointCuts" expression="execution(* com.xxx.yyy..*.*(..))"/> ,注册 AbstractExpressionPointcut 的BeanDefinition。

3.2.1 parsePointcut

private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
		String id = pointcutElement.getAttribute(ID);
		
		// 获取表达式 配置中的 expression="execution(* com.xxx.yyy..*.*(..))"
		String expression = pointcutElement.getAttribute(EXPRESSION);

		AbstractBeanDefinition pointcutDefinition = null;
		try {
			this.parseState.push(new PointcutEntry(id));
			
			// 使用AspectJExpressionPointcut,为pointcut创建BeanDefinition,
			pointcutDefinition = createPointcutDefinition(expression);
			pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));

			String pointcutBeanName = id;
			if (StringUtils.hasText(pointcutBeanName)) {
			     // 以id为beanName注册AspectJExpressionPointcut为bean.
				parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
			}
			else {
			    // 自动生成beanName注册AspectJExpressionPointcut为bean.
				pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition);
			}
			parserContext.registerComponent(
					new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));
		}
		finally {
			this.parseState.pop();
		}

		return pointcutDefinition;
	}
复制代码

3.2.2 createPointcutDefinition

  • 1 aop:pointcut 解析为 AspectJExpressionPointcut 对象。
  • 2 AspectJExpressionPointcut extends AbstractExpressionPointcut
  • 3 expressionAbstractExpressionPointcut 的属性
protected AbstractBeanDefinition createPointcutDefinition(String expression) {
		RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
		beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		beanDefinition.setSynthetic(true);
		beanDefinition.getPropertyValues().add(EXPRESSION, expression);
		return beanDefinition;
	}
复制代码

3.3 解析advisor

解析 <aop:advisor advice-ref="customInterceptor" pointcut-ref="interceptorPointCuts"/> ,注册 DefaultBeanFactoryPointcutAdvisor 的BeanDefinition。

3.3.1 parseAdvisor

createAdvisorBeanDefinition
parsePointcutProperty
private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
	
	    // 1 创建bean : DefaultBeanFactoryPointcutAdvisor
		AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);
		String id = advisorElement.getAttribute(ID);

		try {
			this.parseState.push(new AdvisorEntry(id));
			String advisorBeanName = id;
			
			// 2 注册bean : DefaultBeanFactoryPointcutAdvisor
			if (StringUtils.hasText(advisorBeanName)) {
				parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
			}
			else {
				advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);
			}

            // 3 解析 pointcut-ref="interceptorPointCuts"
			Object pointcut = parsePointcutProperty(advisorElement, parserContext);
			if (pointcut instanceof BeanDefinition) {
			    // 返回的是有`pointcut`构造的BeanDefinition(AspectJExpressionPointcut对象),则设置`DefaultBeanFactoryPointcutAdvisor.pointcut = pointcut`
				advisorDef.getPropertyValues().add(POINTCUT, pointcut);
				parserContext.registerComponent(
						new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
			}
			else if (pointcut instanceof String) {
			   // 返回的是beanName,则设置`DefaultBeanFactoryPointcutAdvisor.pointcut`为一个运行时Bean引用。
				advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
				parserContext.registerComponent(
						new AdvisorComponentDefinition(advisorBeanName, advisorDef));
			}
		}
		finally {
			this.parseState.pop();
		}
	}
复制代码

3.3.2 createAdvisorBeanDefinition

Spring AOP源码实现分步解析
  • 1 创建 DefaultBeanFactoryPointcutAdvisor 的BeanDefinition,DefaultBeanFactoryPointcutAdvisor是 PointcutAdvisor 的一个实现;
  • 2 解析 advice-ref 获取advisor的Bean的beanName,即aop.xml中的customInterceptor。
  • 3 DefaultBeanFactoryPointcutAdvisor extends AbstractBeanFactoryPointcutAdvisor ,使用 advice-ref 设置 adviceBeanName 属性,即前面的 customInterceptor
private static final String ADVICE_BEAN_NAME = "adviceBeanName";
    
	private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) {
	
	    // 创建`DefaultBeanFactoryPointcutAdvisor`的BeanDefinition;
		RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
		advisorDefinition.setSource(parserContext.extractSource(advisorElement));

        // 解析`advice-ref`获取advice的Bean的beanName;
		String adviceRef = advisorElement.getAttribute(ADVICE_REF);
		if (!StringUtils.hasText(adviceRef)) {
			parserContext.getReaderContext().error(
					"'advice-ref' attribute contains empty value.", advisorElement, this.parseState.snapshot());
		}
		else {
		    // 设置AbstractBeanFactoryPointcutAdvisor的adviceBeanName属性
			advisorDefinition.getPropertyValues().add(
					ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));
		}

		if (advisorElement.hasAttribute(ORDER_PROPERTY)) {
			advisorDefinition.getPropertyValues().add(
					ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
		}

		return advisorDefinition;
	}
复制代码

3.3.3 parsePointcutProperty

pointcut
pointcut-ref

所以:pointcut优先于 pointcut-ref,有pointcut就不再解析pointcut-ref。

private Object parsePointcutProperty(Element element, ParserContext parserContext) {
		if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {
			parserContext.getReaderContext().error(
					"Cannot define both 'pointcut' and 'pointcut-ref' on <advisor> tag.",
					element, this.parseState.snapshot());
			return null;
		}
		else if (element.hasAttribute(POINTCUT)) {
			
			// 属性有`pointcut`,则使用expression调用createPointcutDefinition,构造AspectJExpressionPointcut的bean后直接返回。
			String expression = element.getAttribute(POINTCUT);
			AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);
			pointcutDefinition.setSource(parserContext.extractSource(element));
			
			// 返回BeanDefinition
			return pointcutDefinition;
		}
		else if (element.hasAttribute(POINTCUT_REF)) {
			String pointcutRef = element.getAttribute(POINTCUT_REF);
			if (!StringUtils.hasText(pointcutRef)) {
				parserContext.getReaderContext().error(
						"'pointcut-ref' attribute contains empty value.", element, this.parseState.snapshot());
				return null;
			}
			// 返回pointcut-ref的beanName
			return pointcutRef;
		}
		else {
			parserContext.getReaderContext().error(
					"Must define one of 'pointcut' or 'pointcut-ref' on <advisor> tag.",
					element, this.parseState.snapshot());
			return null;
		}
	}
复制代码

3.4 解析过程中注册的BeanDefinition

  • BeanPostProcessor : AspectJAwareAdvisorAutoProxyCreator ,beanName是 org.springframework.aop.config.internalAutoProxyCreator
  • pointcut: AbstractExpressionPointcut ,设置了expression属性;
  • advisor: DefaultBeanFactoryPointcutAdvisor ,pointcut属性设置为 AbstractExpressionPointcut

4 注册BeanPostProcessor

在AbstractApplicationContext.refresh()方法中,创建 ConfigurableListableBeanFactory 后,会执行 registerBeanPostProcessors 向Spring环境注册 BeanPostProcessor

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
复制代码

AspectJAwareAdvisorAutoProxyCreator 在这个时候被加入到用于处理bean创建的BeanPostProcessor列表中。

简要过程如下:

PostProcessorRegistrationDelegate.registerBeanPostProcessors
beanFactory.getBean(ppName, BeanPostProcessor.class);
beanFactory.addBeanPostProcessor(postProcessor)

5 创建Bean并增强

5.1 createProxy

Spring创建Bean,是在 AbstractAutowireCapableBeanFactory.doCreateBean 方法中:

  1. AbstractAutowireCapableBeanFactory.doCreateBean 中调用了 initializeBean
// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
复制代码
  1. initializeBean 中:
if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
复制代码
  1. applyBeanPostProcessorsAfterInitialization 执行了BeanPostProcessor.postProcessAfterInitialization方法:
@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
复制代码
  1. AbstractAutoProxyCreator.postProcessAfterInitialization 就在这里执行:
@Override
	public Object postProcessAfterInitialization(@Nullable 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;
	}
复制代码
  1. wrapIfNecessary 中使用advisor执行createProxy:
// Create proxy if we have advice.

        // 1 查找advisor
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 2 创建proxy,并使用advisor进行增强
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
复制代码

5.2 查找匹配的advisor

AbstractAutoProxyCreator.getAdvicesAndAdvisorsForBean 是一个抽象方法,由子类 AbstractAdvisorAutoProxyCreator 实现。

AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 调用了 findEligibleAdvisors ,主要实现两个流程:

  • 1 获取候选的advisors;
  • 2 过滤出匹配的advisors。
/*
    beanClass:要代理的类
    beanName:当前要代理的bean的beanName
    */
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	    // 1 获取候选的advisors
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 2 过滤出匹配的advisors
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
复制代码

5.2.1 findCandidateAdvisors

调用 BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans ,获取到所有实现了Advisor接口的Bean,主要代码片段如下:

  • 1 找到是有实现了Advisor接口的beanName:

    advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false);

  • 2 根据beanName获取Bean:

    List<Advisor> advisors = new LinkedList<>();
    ....
    advisors.add(this.beanFactory.getBean(name, Advisor.class));
    ....
    return advisors;
    复制代码

5.2.2 findAdvisorsThatCanApply

过滤出匹配的Advisor,主要通过AopUtils.findAdvisorsThatCanApply,调用 canApply 实现:

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new LinkedList<>();
		for (Advisor candidate : candidateAdvisors) {
		    // 调用 canApply
			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;
			}
			// 调用canApply
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
复制代码

5.2.3 canApply

IntroductionAdvisor
PointcutAdvisor
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

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

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

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

		Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}
复制代码

5.3 使用advisor增强代理

AbstractAutoProxyCreator.createProxy 中实现:

  • 1 创建ProxyFactory
  • 2 判断proxyTargetClass
  • 3 buildAdvisors
  • 4 执行getProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

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

        // 创建ProxyFactory
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

        // 判断proxyTargetClass
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

        //  buildAdvisors
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

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

        // 执行getProxy
		return proxyFactory.getProxy(getProxyClassLoader());
	}
复制代码

5.3.1 DefaultAopProxyFactory.createAopProxy

proxyFactory.getProxy 中,需要一个 AopProxy 去实现, AopProxy 的创建,在 DefaultAopProxyFactory 中,返回一个 JdkDynamicAopProxy 或一个 CglibAopProxy

@Override
	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.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
复制代码

5.3.2 JdkDynamicAopProxy

JdkDynamicAopProxy实现了 java.lang.reflect.InvocationHandler 接口,在 invoke(Object proxy, Method method, Object[] args) 中实现代理。代码片段如下:

// Get the interception chain for this method.
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// We need to create a method invocation...
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}
复制代码

调用 ReflectiveMethodInvocation.proceed() 实现了代理。

5.3.3 ObjenesisCglibAopProxy

ObjenesisCglibAopProxy是 CglibAopProxy 的子类,代理逻辑都实现在 CglibAopProxy 里。

CglibAopProxy中获取Callback数组时,创建了DynamicAdvisedInterceptor对象。

private Callback[] getCallbacks(Class<?> rootClass){
    //省略代码
    // Choose an "aop" interceptor (used for AOP calls).
    Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
    //省略代码
}
复制代码

DynamicAdvisedInterceptor 实现了 org.springframework.cglib.proxy.MethodInterceptor 接口,在 intercept 方法里执行了代理:

// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
复制代码

CglibMethodInvocation是 ReflectiveMethodInvocation 的子类,所以也是调用 ReflectiveMethodInvocation.proceed() 实现了代理。

原文  https://juejin.im/post/5df200156fb9a0160376e7b8
正文到此结束
Loading...