Spring AOP源码解析(三)创建代理并调用

一、创建代理准备工作

回顾之前的wrapIfNecessary方法,再获取到匹配的增强器后,Spring就会为拦截的bean创建代理对象:

		//获取匹配的增强器
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		//DO_NOT_PROXY = null
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//创建代理
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

创建代理createProxy:

	protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
		//在bean对应的BeanDefinition中添加原Class对象属性(保存bean原本的Class)
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		//获取当前类中配置的属性
		proxyFactory.copyFrom(this);
		
		//检查proxyTargetClass属性
		if (!proxyFactory.isProxyTargetClass()) {
			//检查beanDefinitioin中是否包含preserveTargetClass属性,且属性为true
			//设置是否使用CGLib进行代理
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				//筛选代理接口并添加到proxyFactory
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		
		//获取增强器(包括前面筛选出来的增强器,以及通过setInterceptorNames中添加的通用增强器,默认为空)
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			//将所有增强器添加到proxyFactory
			proxyFactory.addAdvisor(advisor);
		}
		
		//设置需要代理的bean对象信息
		proxyFactory.setTargetSource(targetSource);
		//模版方法,由子类定制化代理
		customizeProxyFactory(proxyFactory);
		//用来控制代理工程被配置后,是否还允许修改代理的配置,默认为false
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

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

上面代理流程为:

  1. 在BeanDefinition中保存bean原Class对象,因为创建代理后,bean的class会被修改(Spring4中新加入的带你,Spring3中不包含)
  2. 创建ProxyFactory
  3. 设置属性
  4. 过滤目标bean的接口,并添加到ProxyFactory
  5. 获取增强器实例,添加到ProxyFactory中
  6. 创建代理

过滤接口

过滤接口中主要功能是,帮助判断是否使用JDK的动态代理来创建代理。因为JDK动态代理的条件是bean实现了接口,所以Spring会将目标bean实现的接口过滤后添加到ProxyFactory中,方便判断是否使用JDK动态代理,下面是evaluateProxyInterfaces实现:

	protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
		//获取所有实现的接口
		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
		boolean hasReasonableProxyInterface = false;
		for (Class<?> ifc : targetInterfaces) {
			//不是Spring内部回调用的接口 && 不是语言内部接口 && 接口定义了一个以上的方法
			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
					ifc.getMethods().length > 0) {
				hasReasonableProxyInterface = true;
				break;
			}
		}
		//如果满足上面三个条件,才会将接口添加到proxyFactory
		if (hasReasonableProxyInterface) {
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
			for (Class<?> ifc : targetInterfaces) {
				proxyFactory.addInterface(ifc);
			}
		}
		//条件不满足,缺少合适的接口,无法使用JDK动态代理,使用CGLib
		else {
			proxyFactory.setProxyTargetClass(true);
		}
	}

下面是过滤条件:

1.Spring内部接口

会排除掉InitializingBean、DisposableBean、Aware接口

	protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
		return (InitializingBean.class == ifc || DisposableBean.class == ifc ||
				ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
	}

2、是否是语言内部接口 isInternalLanguageInterface

	protected boolean isInternalLanguageInterface(Class<?> ifc) {
		return (ifc.getName().equals("groovy.lang.GroovyObject") ||
				ifc.getName().endsWith(".cglib.proxy.Factory"));
	}

其实就是比较类名

3、接口中是否定义了方法

二、创建代理

ProxyFactory.getProxy:

	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

createAopProxy:

	protected final synchronized AopProxy createAopProxy() {
		//active会在在第一次创建代理后,设为true
		if (!this.active) {
			//设置active为true,并通知监听器(如果没有配置,为空)
			activate();
		}
		//getAopProxyFactory会返回aopProxyFactory变量,默认实现为DefaultAopProxyFactory
		return getAopProxyFactory().createAopProxy(this);
	}

代码流程:

  1. 如果是第一次创建代理,会通知ProxyFactory中注册的监听器
  2. 获取类中定义的aopProxyFactory变量,默认实现为DefaultAopProxyFactory
  3. 通过DefaultAopProxyFactory创建代理对象(会传入当前对象,用于获取配置信息)

DefaultAopProxyFactory-->createAopProxy:

	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			//代理目标bean的Class不能为空
			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.");
			}
			//如果是接口 或者 Class类型为Proxy
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

Spring生成代理对象的方式有两种,JDK动态代理和CGLib,分别生成JdkDynamicAopProxy和ObjenesisCglibAopProxy,从上面代码可以看出Spring的判断条件

  1. optimize:用来控制通过CGLib创建的代理是否使用激进的优化策略(该仅对CGLib有效)
  2. proxyTargetClass:当属性为true,使用CGLib,设置方式:<aop:aspectj-autoproxy proxy-target-class="true">。
  3. 是否存在代理接口(也就是前面过滤接口一节中,添加进去的接口)
  4. 如果目标类是接口的话,还是会使用JDK的方式进行代理

JDK动态代理与CGLib的区别:

  • JDK只能针对实现了接口的类生成代理
  • CGLib是针对类实现代理,主要通过生成目标类的子类,覆盖其中的方法来达到代理的目的。因此,目标类或方法不能被定义为final

三、获取代理对象

回顾之前getProxy创建代理的代码:

	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

getAopProxy就是上一节中获取到的AopProxy实例:JdkDynamicAopProxy或ObjenesisCglibAopProxy,后面会调用其getProxy获取代理对象:

	public Object getProxy(ClassLoader classLoader) {
		//log...
		//获取代理接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		//检查是否在接口中定义了equals或hashCode方法
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		//创建代理对象
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

上面代码流程:

  1. 获取代理接口
  2. 检查是否在接口中定义了equals或hashCode方法
  3. 使用JDK动态代理Proxy.newProxyInstance创建代理对象

四、方法拦截过程

JDK生成代理对象需要调用return Proxy.newProxyInstance,并传入类加载器、代理接口、以及一个InvocationHandler实例。其中InvocationHandler的invoke方法定义了代理的流程。

上面代码中,传入的InvocationHandler是this,即JdkDynamicAopProxy,该类实现了InvocationHandler接口,下面是其invoke方法实现:

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;

		//获取原对象信息
		TargetSource targetSource = this.advised.targetSource;
		Class<?> targetClass = null;
		Object target = null;

		try {
			//如果接口中定义了equals或hashCode方法,则进行专门处理
			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);
			}
			//opaque属性,表示是否禁止将代理对象转换为Advised对象,默认是false
			//如果调用的方法来自Advised接口
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				//通过反射Method.invoke,调用advised(传入的ProxyFactory实例,该类实现了Advised接口)对应的方法
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;
			//为了解决目标对象内部的自我调用无法实施切面中的增强,需要暴露代理对象
			if (this.advised.exposeProxy) {
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// 获取目标对象信息
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}

			// 获取当前方法的拦截器链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// 如果没有任何拦截器,则调用直接对原目标对象调用方法
			if (chain.isEmpty()) {
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// 将拦截器链封装到ReflectiveMethodInvocation,方便使用其proceed进行链式调用拦截器
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, 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())) {
				// 特殊情况:为了防止方法返回"return this",返回原目标对象,会将返回值替换为代理对象
				retVal = proxy;
			}
			//如果返回类型是基本类型兵器,但是返回结果为null,抛出异常
			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);
			}
		}
	}

代码流程:

  1. 特殊方法的处理,包括equalshashCode方法以及定义在Advised接口中的方法
  2. 获取方法匹配的增强器,并生成拦截器链并调用
  3. 对方法返回结果进行处理:如果返回“this”,即原目标对象,则会替换为返回代理对象;如果返回结果为null,但返回类型为基本数据类型(int、char等)则抛出异常

1、获取匹配的拦截器:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
		//缓存的cacheKey,先尝试从缓存获取,不存在再从ProxyFactory中解析
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			//通过实例方法和ProxyFactory中保存的信息,解析出匹配的增强
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

方法匹配增强器的功能交由advisorChainFactory(DefaultAdvisorChainFactory)完成:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass) {

		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		//方法是否匹配引介增强
		boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		
		//遍历增强器
		for (Advisor advisor : config.getAdvisors()) {
			//PointcutAdvisor类型的增强器
			//通过@Aspect加入的增强器类型为InstantiationModelAwarePointcutAdvisorImpl,实现了PointcutAdvisor
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			//对于引介增强的处理
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

上面代码首先会遍历拦截增强器,然后根据目标类和目标方法(引介增强外)匹配增强器,如果匹配的话,返回增强器包装的拦截器(Advice)

对于@Aspect注解配置类中,@Before、@After、@AfterThrowing配置的增强会被包装为AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice等,在这一步骤中,这些Advice会分别被封装为MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor拦截器。

 

2、创建拦截器链并调用

Spring会在获取到方法匹配的拦截器后,将代理对象、目标对象、调用方法、参数、拦截器等信息封装到ReflectiveMethodInvocation中:

	protected ReflectiveMethodInvocation(
			Object proxy, Object target, Method method, Object[] arguments,
			Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = BridgeMethodResolver.findBridgedMethod(method);
		this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}

然后调用ReflectiveMethodInvocation的proceed方法:

	public Object proceed() throws Throwable {
		//	执行完所有增强后,执行切点方法
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		
		//获取下一个拦截器
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			//动态匹配
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				//不匹配则不执行拦截器
				return proceed();
			}
		}
		else {
			// 普通拦截器。比如:MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

通过currentInterceptorIndex记录当前拦截器的索引,每调用一个拦截器就+1,再次调用proceed方法时就会获取下一个拦截器调用。

3、拦截器调用

在获取增强器的过程中,例如@Before注解标注的方法会被封装为AspectJMethodBeforeAdvice,然后会在 1.获取匹配的拦截器 过程中,会被包装为MethodInterceptor(MethodBeforeAdviceInterceptor),下面是Advice转换为MethodInterceptor的过程:

DefaultAdvisorAdapterRegistry.getInterceptors:

	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
		//获取Advice
		Advice advice = advisor.getAdvice();
		//如果Advice实例同时已经实现MethodInterceptor接口,则直接使用
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		//需要使用适配器来转换Advice接口
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
	}

代码流程:

  1. 如果Advice增强已经实现了MethodInterceptor,则不需要转换,可以直接使用。例如:@After注解标注的增强方法会被表示为AspectJAfterAdvice,该类同时实现了Advice和MethodInterceptor接口,也就是已经在类中规定好了拦截的逻辑。
  2. Advice实现了没有同时实现MethodInterceptor,所以需要使用内置的适配器将Advice增强转换为MethodInterceptor拦截器。

a、内置的Advice适配器

在前面的代码中,将Advice转换为MethodInterceptor的工作是交给this.adapters来完成的,该变量定义如下;

private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);

并且在DefaultAdvisorAdapterRegistry的构造函数中,对该变量进行了初始化填充:

	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

可以看到,Spring实现会加入3个默认的是Advice适配器:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter。

这三个适配器通过support方法,验证是否是否支持传入的Advice对象,如果支持,会将Advice实例封装为对应的MethodInterceptor实例:

MethodBeforeAdviceAdapter:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

AfterReturningAdviceAdapter:

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
		return new AfterReturningAdviceInterceptor(advice);
	}

}

ThrowsAdviceAdapter:

class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof ThrowsAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		return new ThrowsAdviceInterceptor(advisor.getAdvice());
	}

}

下面是对三种适配器的总结:

适配器支持的Advice接口Advice实现类对应注解
MethodBeforeAdviceAdapterMethodBeforeAdviceAspectJMethodBeforeAdvice@Before
AfterReturningAdviceAdapterAfterReturningAdviceAspectJAfterReturningAdvice@AfterReturning
ThrowsAdviceAdapterThrowsAdvice

 

 

 

 

 

下面再来总结一下通过注解配置的增强对应的拦截器:

注解AdviceMethodInterceptor
@BeforeAspectJMethodBeforeAdviceMethodBeforeAdviceInterceptor
@AfterAspectJAfterAdviceAspectJAfterAdvice
@AfterReturningAspectJAfterReturningAdviceAfterReturningAdviceInterceptor
@AfterThrowingAspectJAfterThrowingAdviceAspectJAfterThrowingAdvice
@Around AspectJAroundAdviceAspectJAroundAdvice

 

 

 

 

 

 

 

b、拦截器调用

拦截器的类型有多中,下面我们分析由@Before注解添加的拦截器MethodBeforeAdviceInterceptor。

MethodBeforeAdviceInterceptor定义:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

	private MethodBeforeAdvice advice;

	/**
	 * 将传入的MethodBeforeAdvice封装为MethodBeforeAdviceInterceptor
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}
}

从invoke方法中可以看到,拦截器会在调用真正方法前,调用MethodBeforeAdvice的before方法,在这一步,也就完成了方法的前置增强。

下面看一下AspectJMethodBeforeAdvice的before实现:

	public void before(Method method, Object[] args, Object target) throws Throwable {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}
	
	protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
		//将参数绑定后,传入invokeAdviceMethodWithGivenArgs方法执行
		return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
	}

invokeAdviceMethodWithGivenArgs:

	protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		//如果advice增强方法参数为空
		if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
			actualArgs = null;
		}
		try {
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// 通过反射,调用增强方法
			return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
		}
		catch (IllegalArgumentException ex) {
			throw new AopInvocationException("Mismatch on arguments to advice method [" +
					this.aspectJAdviceMethod + "]; pointcut expression [" +
					this.pointcut.getPointcutExpression() + "]", ex);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}

 

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值