浅析AOP源码(四)

转载自:https://blog.youkuaiyun.com/luanlouis/article/details/51155821

  

1、Spring内部创建代理对象的过程

  在Spring的底层,如果配置了AOP,Spring会为每一个Bean创建一个对应的ProxyFactoryBean的FactoryBean来创建某个对象的代理对象。
  假定有一个接口TicketService及其实现类RailwayStation,打算创建一个代理类,在执行TicketService的方法时的各个阶段,插入对应的业务代码。

public interface TicketService {
    //售票
    public void sellTicket();

    //问询
    public void inquire();

    //退票
    public void withdraw();
}
public class RailwayStation  implements TicketService {
    public void sellTicket(){
        System.out.println("售票............");
    }

    public void inquire() {
        System.out.println("问询.............");
    }

    public void withdraw() {
        System.out.println("退票.............");
    }
}
public class TicketServiceBeforeAdvice implements MethodBeforeAdvice {

    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("BEFORE_ADVICE: 欢迎光临代售点....");
    }
}
public class TicketServiceAfterReturningAdvice  implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("AFTER_RETURNING:本次服务已结束....");
    }
}
public class TicketServiceAroundAdvice  implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("AROUND_ADVICE:BEGIN....");
        Object returnValue = invocation.proceed();
        System.out.println("AROUND_ADVICE:END.....");
        return returnValue;
    }
}
public class TicketServiceThrowsAdvice implements ThrowsAdvice {

    public void afterThrowing(Exception ex) {
        System.out.println("AFTER_THROWING....");
    }

    public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
        System.out.println("调用过程出错啦!!!!!");
    }

}

  然后来手动使用ProxyFactoryBean来创建Proxy对象,并将相应的几种不同的Advice加入这个proxy对应的各个执行阶段中:

    public static void main(String[] args) {
        Advice beforeAdvice = new TicketServiceBeforeAdvice();
        Advice afterReturningAdvice = new TicketServiceAfterReturningAdvice();
        Advice aroundAdvice = new TicketServiceAroundAdvice();
        Advice throwsAdvice = new TicketServiceThrowsAdvice();

        RailwayStation railwayStation = new RailwayStation();

        // 创建ProxyFactoryBean,用以创建指定对象的Proxy对象
        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        // 设置Proxy的接口
        proxyFactoryBean.setInterfaces(TicketService.class);
        // 设置RealSubject
        proxyFactoryBean.setTarget(railwayStation);
        // 使用JDK基于接口实现机制的动态代理生成Proxy代理对象,如果想使用CGLIB,需要将这个flag设置成true
        proxyFactoryBean.setProxyTargetClass(false);

        // 添加不同的Advice
        proxyFactoryBean.addAdvice(afterReturningAdvice);
        proxyFactoryBean.addAdvice(aroundAdvice);
        proxyFactoryBean.addAdvice(throwsAdvice);
        proxyFactoryBean.addAdvice(beforeAdvice);

        // 通过ProxyFactoryBean生成Proxy对象
        TicketService ticketService = (TicketService) proxyFactoryBean.getObject();
        ticketService.sellTicket();
    }

  运行结果:

AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....

  我们成功地创建了一个通过一个ProxyFactoryBean和真实的实例对象创建出了对应的代理对象,并将各个Advice加入到proxy代理对象中。

  

2、Spring AOP的核心ProxyFactoryBean

  上面通过了使用ProxyFactoryBean实现了AOP的功能,在使用时通过addAdvice(Advice advice)把各类Advice添加到ProxyFactoryBean(实际是父类AdvisedSupport)中:

	public void addAdvice(Advice advice) throws AopConfigException {
		int pos = this.advisors.size();
		addAdvice(pos, advice);
	}

  AdvisedSupport中维护了private List<Advisor> advisors = new LinkedList<Advisor>();列表,addAdvice中会把advice包装为DefaultPointcutAdvisor加入到这个列表里。
  也就是说ProxyFactoryBean知道Advice信息,可以根据特定的类名和方法名返回对应的AdviceChain,用以表示需要执行的Advice串。当使用proxy时,对proxy对象调用的方法,都最终被转到这个类的invoke()方法中。以JdkDynamicAopProxy为例:

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
  //...略
	/** Proxy的配置信息,这里主要提供Advisor列表,并用于返回AdviceChain */
	private final AdvisedSupport advised;
 
	//...略
	@Override
	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 {
			//...略
			Object retVal;

      //...略
			// 获取当前调用方法的拦截链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
 
      // 如果没有拦截链,则直接调用Joinpoint连接点的方法。
			if (chain.isEmpty()) {
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
        // 根据给定的拦截链和方法调用信息,创建新的MethodInvocation对象,
        // 整个拦截链的工作逻辑都在这个ReflectiveMethodInvocation里 
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				retVal = invocation.proceed();
			}
 
			//...略
			return retVal;
		}
		finally {
			//...略
		}
	}
}

  来看关键的getInterceptorsAndDynamicInterceptionAdvice函数:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

  最终是调用到了DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice:

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

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		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()) {
			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) {
				//...略
			}
			else {
				//...略
			}
		}

		return interceptorList;
	}

  代码比较长,主要看for循环的第一个if分支。config.getAdvisors()返回的就是之前通过addAdvisor添加的Advisor列表(new DefaultPointcutAdvisor(advice))。registry.getInterceptors(advisor)是把advisor转换成MethodInterceptor[]:

	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) 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()]);
	}

  AdvisorAdapter的实例有AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter分别用于转换AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice为AfterReturningAdviceInterceptor、MethodBeforeAdviceInterceptor、ThrowsAdviceInterceptor。注意,示例代码里的TicketServiceAroundAdvice类是MethodInterceptor的子类,不需要AdvisorAdapter转换。

  这里创建MethodInterceptor链,然后构造ReflectiveMethodInvocation实例,调用proceed()

	@Override
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
    
    // 取得第拦截器链上第N个拦截器 
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

  初始时,this.currentInterceptorIndex=-1this.interceptorsAndDynamicMethodMatchers即先前创建的MethodInterceptor[]。
  第一步,取MethodInterceptor[]中的第0个,即AfterReturningAdviceInterceptor:

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;

	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

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

  先执行mi.proceed(),即ReflectiveMethodInvocation实例的proceed()方法,进入proceed()后,取MethodInterceptor[]中的第1个,即TicketServiceAroundAdvice:

public class TicketServiceAroundAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("AROUND_ADVICE:BEGIN....");
        Object returnValue = invocation.proceed();
        System.out.println("AROUND_ADVICE:END.....");
        return returnValue;
    }
}

  同理再次进入proceed()后,取MethodInterceptor[]中的第2个,即ThrowsAdviceInterceptor:

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		catch (Throwable ex) {
			Method handlerMethod = getExceptionHandler(ex);
			if (handlerMethod != null) {
				invokeHandlerMethod(mi, ex, handlerMethod);
			}
			throw ex;
		}
	}

  之后进入proceed()后,取MethodInterceptor[]中的第3个,MethodBeforeAdviceInterceptor:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

	private MethodBeforeAdvice advice;

	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();
	}

}

  之后进入proceed(),this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1满足条件,进入invokeJoinpoint:

	protected Object invokeJoinpoint() throws Throwable {
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}

  这里执行被代理对象的方法调用。然后根据方法栈的调用依次执行完MethodBeforeAdviceInterceptor->ThrowsAdviceInterceptor->TicketServiceAroundAdvice->AfterReturningAdviceInterceptor。所以最终的运行情况是:

AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....
根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为种: 无监督(unsupervised) 训练数据没有给定...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值