Aop原理解析

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进行了层层的调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值