阅读 790

Spring AOP源码实现分步解析

1 概述

1.1 示例

最基本的使用,在创建了业务接口和实现类后,通过配置<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());

所以:

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

3 ConfigBeanDefinitionParser

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

  • 1 向Spring环境注册一个BeanDefinition:AspectJAwareAdvisorAutoProxyCreator
  • 2 将xml配置的pointcut,advisor等解析为一系列BeanDefinition。
@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

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

  • 1 调用createAdvisorBeanDefinition创建advisor;
  • 2 调用parsePointcutProperty获取pointcut。
	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

  • 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

  • 1 属性有pointcut,则使用expression调用createPointcutDefinition,构造AspectJExpressionPointcut的bean后直接返回。
  • 2 否则返回pointcut-ref指定的bean作为Pointcut。

所以: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列表中。

简要过程如下:

  • 1 调用PostProcessorRegistrationDelegate.registerBeanPostProcessors
  • 2 通过beanFactory.getBean(ppName, BeanPostProcessor.class);获取BeanPostProcessor列表;
  • 3 执行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

  • 1 如果接口是IntroductionAdvisor,则调用IntroductionAdvisor.ClassFilter.matchs进行判断;
  • 2 如果接口是PointcutAdvisor(比如前面创建的DefaultBeanFactoryPointcutAdvisor),则先调用PointcutAdvisor.ClassFilter.matches进行判断,再MethodMatcher.getMethodMatcher()进行判断。
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()实现了代理。

关注下面的标签,发现更多相似文章
评论