Aop原理解析
准备工作
-
定义aop配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--目标对象 --> <bean id="userService" class="com.yalong.spring.service.xml.XMLUserServiceImpl"> </bean> <!--通知对象 --> <bean id="adevise" class="com.yalong.spring.service.xml.Adevise"></bean> <aop:config> <aop:aspect ref="adevise"> <!--切入点 --> <aop:pointcut id="point" expression="execution(* com.yalong.spring.service.xml.XMLUserServiceImpl.*(..))"></aop:pointcut> <!--前置通知 --> <aop:before method="before" pointcut-ref="point"></aop:before> </aop:aspect> </aop:config> </beans>
-
目标对象类
public class XMLUserServiceImpl implements UserService { @Override public void delete(int id) { if (id == 0) { return; } } }
-
通知类
public class Adevise { public void before() { System.out.println("===================before method==================="); } }
-
测试类
public class TestBasedXML { @Test public void test() { ApplicationContext ac = new ClassPathXmlApplicationContext("project/spring-xml.xml"); UserService userService = ac.getBean(UserService.class); userService.delete(0); System.out.println(userService); } }
找Aop入口
对BeanDefinition的特殊处理
直接从DefaultBeanDefinitionDocumentReader解析Document入手:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 加载的Document对象是否使用了Spring默认的XML命名空间(beans命名空间) if (delegate.isDefaultNamespace(root)) { // 获取Document对象根元素的所有子节点(bean标签、import标签、alias标签和其他自定义标签context、aop等) NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; // bean标签、import标签、alias标签,则使用默认解析规则 if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else {//像context标签、aop标签、tx标签,则使用用户自定义的解析规则解析元素节点 delegate.parseCustomElement(ele); } } } } else { // 如果不是默认的命名空间,则使用用户自定义的解析规则解析元素节点 delegate.parseCustomElement(root); } }
根据标签的命名空间,解析Aop的自定义标签,找到对应的namespace处理器:
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { // 获取命名空间URI(就是获取beans标签的xmlns:aop或者xmlns:context属性的值) String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } // 根据不同的命名空间URI,去匹配不同的NamespaceHandler(一个命名空间对应一个NamespaceHandler) // 此处会调用DefaultNamespaceHandlerResolver类的resolve方法 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的解析方法 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
第9行,resolve方法定义,从META-INF/spring.handlers获取aop命名空间所对应的namespace处理器:
public NamespaceHandler resolve(String namespaceUri) { // 读取spring所有工程的META-INF/spring.handlers文件,获取namespaceUri和NamespaceHandler的映射关系 Map<String, Object> handlerMappings = getHandlerMappings(); // 获取 指定namespaceUri对应的namespaceHandler Object handlerOrClassName = handlerMappings.get(namespaceUri); if (handlerOrClassName == null) { return null; } else if (handlerOrClassName instanceof NamespaceHandler) { return (NamespaceHandler) handlerOrClassName; } else { // META-INF/spring.handlers文件中存储的value都是String类型的类名 String className = (String) handlerOrClassName; try { // 根据类名通过反射获取到NamespaceHandler的Class类对象 Class<?> handlerClass = ClassUtils.forName(className, this.classLoader); if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri + "] does not implement the [" + NamespaceHandler.class.getName() + "] interface"); } // 实例化NamespaceHandler NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); // 调用NamespaceHandler类的init方法,初始化一些专门处理指定标签的BeanDefinitionParsers类 namespaceHandler.init(); // 将namespaceUri对应的String类型的类名,替换为NamespaceHandler对象,下一次再获取的话,就不会重复创建实例 handlerMappings.put(namespaceUri, namespaceHandler); return namespaceHandler; } catch (ClassNotFoundException ex) { throw new FatalBeanException("Could not find NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", ex); } catch (LinkageError err) { throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", err); } } }
并执行init方法,获取aop:config标签对应的解析器:
public void init() { // In 2.0 XSD as well as in 2.1 XSD. // <aop:config></aop:config>对应的BeanDefinitionParser registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); }
parseCustomElement最后交给ConfigBeanDefinitionParser解析:
public BeanDefinition parse(Element element, ParserContext parserContext) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); // 向IoC容器中注册 AspectJAwareAdvisorAutoProxyCreator 类的BeanDefinition:(用于创建AOP代理对象的) // BeanPostProcessor可以对实例化之后的bean进行一些操作 // AspectJAwareAdvisorAutoProxyCreator 实现了BeanPostProcessor接口,可以对目标对象实例化之后,创建对应的代理对象 configureAutoProxyCreator(parserContext, element); // 获取<aop:config>标签的子标签<aop:aspect>、<aop:advisor> 、<aop:pointcut> List<Element> childElts = DomUtils.getChildElements(element); for (Element elt: childElts) { // 获取子标签的节点名称或者叫元素名称 String localName = parserContext.getDelegate().getLocalName(elt); if (POINTCUT.equals(localName)) { // 解析<aop:pointcut>标签 // 产生一个AspectJExpressionPointcut的BeanDefinition对象,并注册 parsePointcut(elt, parserContext); } else if (ADVISOR.equals(localName)) { // 解析<aop:advisor>标签 // 产生一个DefaultBeanFactoryPointcutAdvisor的BeanDefinition对象,并注册 parseAdvisor(elt, parserContext); } else if (ASPECT.equals(localName)) { // 解析<aop:aspect>标签 // 产生了很多BeanDefinition对象 // aop:after等标签对应5个BeanDefinition对象 // aop:after标签的method属性对应1个BeanDefinition对象 // 最终的AspectJPointcutAdvisor BeanDefinition类 parseAspect(elt, parserContext); } } parserContext.popAndRegisterContainingComponent(); return null; }
重点查看第33行,parseAspect:
private void parseAspect(Element aspectElement, ParserContext parserContext) { // 获取<aop:aspect>标签的id属性值 String aspectId = aspectElement.getAttribute(ID); // 获取<aop:aspect>标签的ref属性值,也就是增强类的引用名称 String aspectName = aspectElement.getAttribute(REF); try { this.parseState.push(new AspectEntry(aspectId, aspectName)); List<BeanDefinition> beanDefinitions = new ArrayList<>(); List<BeanReference> beanReferences = new ArrayList<>(); // 处理<aop:aspect>标签的<aop:declare-parents>子标签 List<Element> declareParents = DomUtils.getChildElementsByTagName(aspectElement, DECLARE_PARENTS); for (int i = METHOD_INDEX; i < declareParents.size(); i++) { Element declareParentsElement = declareParents.get(i); beanDefinitions.add(parseDeclareParents(declareParentsElement, parserContext)); } // We have to parse "advice" and all the advice kinds in one loop, to get the // ordering semantics right. // 获取<aop:aspect>标签的所有子标签 NodeList nodeList = aspectElement.getChildNodes(); boolean adviceFoundAlready = false; for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); // 判断是否是<aop:before>、<aop:after>、<aop:after-returning>、<aop:after-throwing method="">、<aop:around method="">这五个标签 if (isAdviceNode(node, parserContext)) { if (!adviceFoundAlready) { adviceFoundAlready = true; if (!StringUtils.hasText(aspectName)) { parserContext.getReaderContext().error( "<aspect> tag needs aspect bean reference via 'ref' attribute when declaring advices.", aspectElement, this.parseState.snapshot()); return; } beanReferences.add(new RuntimeBeanReference(aspectName)); } // 解析<aop:before>等五个子标签 // 方法主要做了三件事: // 1、根据织入方式(before、after这些)创建RootBeanDefinition,名为adviceDef即advice定义 // 2、将上一步创建的RootBeanDefinition写入一个新的RootBeanDefinition,构造一个新的对象,名为advisorDefinition,即advisor定义 // 3、将advisorDefinition注册到DefaultListableBeanFactory中 AbstractBeanDefinition advisorDefinition = parseAdvice( aspectName, i, aspectElement, (Element) node, parserContext, beanDefinitions, beanReferences); beanDefinitions.add(advisorDefinition); } } AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition( aspectElement, aspectId, beanDefinitions, beanReferences, parserContext); parserContext.pushContainingComponent(aspectComponentDefinition); // 得到所有<aop:aspect>下的<aop:pointcut>子标签 List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT); for (Element pointcutElement : pointcuts) { // 解析<aop:pointcut>子标签 parsePointcut(pointcutElement, parserContext); } parserContext.popAndRegisterContainingComponent(); } finally { this.parseState.pop(); } }
处理aop:before、aop:after、aop:after-returning、<aop:after-throwing method="">、<aop:around method="">这五个标签,如果是五个标签则进入parseAdvice
private AbstractBeanDefinition parseAdvice( String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext, List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) { try { this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement))); // create the method factory bean // 创建方法工厂Bean的BeanDefinition对象:用于获取Advice增强类的Method对象 RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class); // 设置MethodLocatingFactoryBean的targetBeanName为advice类的引用名称 methodDefinition.getPropertyValues().add("targetBeanName", aspectName); // 设置MethodLocatingFactoryBean的methodName为<aop:after>标签的method属性值(也就是advice方法名称) methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method")); methodDefinition.setSynthetic(true); // create instance factory definition // 创建实例工厂BeanDefinition:用于创建增强类的实例 RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class); // 设置SimpleBeanFactoryAwareAspectInstanceFactory的aspectBeanName为advice类的引用名称 aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName); aspectFactoryDef.setSynthetic(true); //以上的两个BeanDefinition的作用主要是通过反射调用Advice对象的指定方法 // method.invoke(obj,args) // register the pointcut // 通知增强类的BeanDefinition对象(核心) AbstractBeanDefinition adviceDef = createAdviceDefinition( adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef, beanDefinitions, beanReferences); // configure the advisor // 通知器类的BeanDefinition对象 RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class); advisorDefinition.setSource(parserContext.extractSource(adviceElement)); // 给通知器类设置Advice对象属性值 advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef); if (aspectElement.hasAttribute(ORDER_PROPERTY)) { advisorDefinition.getPropertyValues().add( ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY)); } // register the final advisor // 将advisorDefinition注册到IoC容器中 parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition); return advisorDefinition; } finally { this.parseState.pop(); } }
根据织入方式(before、after这些)创建RootBeanDefinition,名为adviceDef即advice定义,
进入getAdviceClass定义方法,不同的切入方式对应不同的Class:
private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) { // 获取标签名称,比如aop:before标签对应的标签名是before String elementName = parserContext.getDelegate().getLocalName(adviceElement); // 处理<aop:before>标签 if (BEFORE.equals(elementName)) { return AspectJMethodBeforeAdvice.class; } // 处理<aop:after>标签 else if (AFTER.equals(elementName)) { return AspectJAfterAdvice.class; } // 处理<aop:after-returning>标签 else if (AFTER_RETURNING_ELEMENT.equals(elementName)) { return AspectJAfterReturningAdvice.class; } // 处理<aop:after-throwing>标签 else if (AFTER_THROWING_ELEMENT.equals(elementName)) { return AspectJAfterThrowingAdvice.class; } // 处理<aop:aroud>标签 else if (AROUND.equals(elementName)) { return AspectJAroundAdvice.class; } else { throw new IllegalArgumentException("Unknown advice kind [" + elementName + "]."); } }
基于此advice定义构造一个新的对象,名为advisorDefinition,即advisor定义
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class); advisorDefinition.setSource(parserContext.extractSource(adviceElement)); // 给通知器类设置Advice对象属性值 advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef); if (aspectElement.hasAttribute(ORDER_PROPERTY)) { advisorDefinition.getPropertyValues().add( ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY)); }
将BeanDefinition注册到DefaultListableBeanFactory中:
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
pointcut处理:
private void parseAspect(Element aspectElement, ParserContext parserContext) { ... // 得到所有<aop:aspect>下的<aop:pointcut>子标签 List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT); for (Element pointcutElement : pointcuts) { // 解析<aop:pointcut>子标签 parsePointcut(pointcutElement, parserContext); } } finally { this.parseState.pop(); } }
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) { // <aop:pointcut>标签的id属性 String id = pointcutElement.getAttribute(ID); // <aop:pointcut>标签的expression属性 String expression = pointcutElement.getAttribute(EXPRESSION); AbstractBeanDefinition pointcutDefinition = null; try { this.parseState.push(new PointcutEntry(id)); // 此处创建一个 AspectJExpressionPointcut 类对应的BeanDefinition对象,处理pointcut pointcutDefinition = createPointcutDefinition(expression); // 解析源是<aop:pointcut> pointcutDefinition.setSource(parserContext.extractSource(pointcutElement)); String pointcutBeanName = id; // 如果配置id属性,则走下面代码 if (StringUtils.hasText(pointcutBeanName)) { parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition); } // 如果没有配置id属性,则走下面代码 else { pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition); } parserContext.registerComponent( new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression)); } finally { this.parseState.pop(); } return pointcutDefinition; }
对Bean的特殊处理
AspectJAwareAdvisorAutoProxyCreator 实现了BeanPostProcessor接口,可以对目标对象实例化之后,创建对应的代理对象
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; }
跟进方法wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } // Advice/Pointcut/Advisor/AopInfrastructureBean接口的beanClass不进行代理以及对beanName为aop内的切面名也不进行代理 // 此处可查看子类复写的shouldSkip()方法 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 查找对代理类相关的advisor对象集合,此处就与ponit-cut表达式有关了 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 对相应的advisor不为空才采取代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 通过jdk动态代理或者cglib动态代理,产生代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 放入代理类型缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // 放入通知缓存 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
查找哪些目标对象需要代理:
protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { // 候选的Advisors List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 合格的Advisors List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<>(); for (Advisor candidate : candidateAdvisors) { 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; } if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
整个方法的主要判断都围绕canApply展开:
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<>(); if (!Proxy.isProxyClass(targetClass)) { classes.add(ClassUtils.getUserClass(targetClass)); } classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(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; }
如果获取到的advisor数组不为空,则为目标对象生成代理:
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 对相应的advisor不为空才采取代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 通过jdk动态代理或者cglib动态代理,产生代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 放入代理类型缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; }
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 = new ProxyFactory(); proxyFactory.copyFrom(this); //如果没有使用CGLib代理 if (!proxyFactory.isProxyTargetClass()) { // 是否可能使用CGLib代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { // 查看beanClass对应的类是否含有InitializingBean.class/DisposableBean.class/Aware.class接口 // 无则采用JDK动态代理,有则采用CGLib动态代理 evaluateProxyInterfaces(beanClass, proxyFactory); } } // 获得所有关联的Advisor集合(该分支待补充) Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // 此处的targetSource一般为SingletonTargetSource proxyFactory.setTargetSource(targetSource); // 空的实现 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); // 是否设置预过滤模式,此处针对本文为true if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 获取使用JDK动态代理或者cglib动态代理产生的对象 return proxyFactory.getProxy(getProxyClassLoader()); }
public Object getProxy(@Nullable ClassLoader classLoader) { // 1、创建JDK方式的AOP代理或者CGLib方式的AOP代理 // 2、调用具体的AopProxy来创建Proxy代理对象 return createAopProxy().getProxy(classLoader); }
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // 创建JDK方式的AOP代理或者CGLib方式的AOP代理 return getAopProxyFactory().createAopProxy(this); }
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } // 获取完整的代理接口 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); // 调用JDK动态代理方法 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
代理方法调用:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // 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. // 检查是否我们有一些通知。如果我们没有,我们可以直接对目标类进行反射调用,避免创建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(); } // Massage return value if necessary. Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { // Special case: it returned "this" and the return type of the method // is type-compatible. Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
第61行,List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass),获取AdvisedSupport中的所有拦截器和动态拦截器列表,用于拦截方法。
如果拦截器列表不为空,则通过proceed方法对原方法进行拦截,里面使用到了递归的思想对chain中的Object进行了层层的调用。