Spring AOP的实现:拦截器链的生成以及Advice通知的实现

版权声明: https://blog.csdn.net/qq1641530151/article/details/83243896

拦截器链的获取生成

上一次我说到了拦截器链的获取,拦截器链的获取以及生成是从一个DefaultAdvisorChainFactory类中得到的。我们来看一下具体的实现代码

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

首先声明一条拦截器链,作为最后的返回的结果。

List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);

这个方法的入参我们可以看到有一个config,这个config就是之前的ProxyFactoryBean对象。这个方法从这个里面获取到通知器(Advistor)。拦截器链是通过AdvisorAdapterRegistry来加入的。这个AdvisorAdapterRegistry对advice织入起了很大的作用。

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

通过一个通知器获得一条拦截器链,然后将这个拦截器链加入到之前声明的interceptorList 中。

这里的advistor通知器是从AdvisorSupport中取得的。

这个方法的实现可以从我们之前的initializeAdvisorChain方法去寻找。

之前的interceptorNames就在我们的之前的xml文件中配置了。通过获取interceptorNames中的name可以获得

我们需要的advisor,是通过getBean()方法来获取

advice = this.beanFactory.getBean(name);

advisor通知器的取得是由IoC容器完成的,但是在ProxyFactoryBean中是如何获得,然后通过回调IoC容器的getBean方法来得到需要的通知器呢?这涉及到IoC的实现原理,我们可以查看AbstractAutowireCapableBeanFactory,可以看到一个对Bean进行初始化的initializeBean方法。在这个Bean的初始化过程中,对IoC容器在Bean的回调中进行了设置,如果这个Bean实现了BeanFactoryAware定义的接口方法就可以调用IoC容器。

Advice通知的实现

之前的代码分析可以看到Aop代理对象和拦截器链都已经建立了起来,但是具体对于目标对象的目标方法还没有建立起来。

从代码的实现中,我们可以看到

扫描二维码关注公众号,回复: 3821784 查看本文章
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

    在GlobalAdvisorAdapterRegistry中隐藏着不少AOP实现的重要细节,它的获取我们可以来看一下

private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

这个DefaultAdvistorAdapterRegistry中设置了一系列的adapter适配器,正是这些adapater适配器的实现,为Spring AOP的advice提供编织能力。我们来看一下实现的代码。

这个链表配置的是一系列的适配器

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

 在构造方法里面我们可以看到这个adapters里面装入的是三个适配器类型

public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
		this.adapters.add(adapter);
	}

这个是在DefaultAdvisorChainFactory中启动的getInteceptors方法

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

我们可以看到如何对通知器进行适配,使用已经配置好的适配器Adapter: MethodBeforeAdviceAdapter,

AfterReturningAdviceAdapter以及ThrowsAdviceAdapter,然后从对应的adapeter中取出封装好的AOP编织功能的拦截器。

我们来看看这三个拦截器是如何实现对方法的增强的。

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

我们进入MethodBeforeAdviceInterceptor类中来看一下具体是怎么实现的。

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

这个方法就是拦截器的回调方法,会在代理方法被调用的时候触发回调。

同理我们可以在书上看到其他两个方法的实现原理和这个是类似的。

至此Spring AOP的实现原理就已经结束了。只能说书上讲述的原理流程还是比较清楚的。但是作为初学者的我来说即使看了不止一遍也还是有些不太理解。所以下一次我会把整个Spring AOP的流程再具体讲一下。作为一个总结和收尾。然后开始Spring MVC的实现流程机制。

猜你喜欢

转载自blog.csdn.net/qq1641530151/article/details/83243896