【spring源码系列-AOP原理探索二】

前文回顾

aop原理探索一主要讲了aop的实现机制、核心实现类以及bean初始化时前置处理器流程。接下来我们来看创建代理对象流程。

创建代理对象

我们知道创建代理对象是 Bean 完成实例化后在初始化的时候创建的代理对象,也就是说我们要回到 AbstractAutowireCapableBeanFactory#doCreateBean 的 AbstractAutowireCapableBeanFactory#initializeBean 方法中去寻找相关逻辑,主要关注 BeanPostProcessors 初始化后处理,也就是 this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 这行代码。同样关于 Bean 的加载到 doCreateBean 方法的源码我们不在分析,到源码系列-IOC容器二去回顾一下。

AbstractAutoProxyCreator#postProcessAfterInitialization

首先从缓存中获取 Bean,判断在 Bean 的早期引用中是否有当前 Bean,如果没有就尝试创建 Bean 的代理对象。主要方法也就是这里的wrapIfNecessary了。

//AbstractAutoProxyCreator#postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		//根据 class 和 beanName 从缓存中获取 
		Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
		//在bean 的早期引用缓存中是否有 当前baan
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			//没有当前 bean 尝试创建代理对象
			return this.wrapIfNecessary(bean, beanName, cacheKey);
		}
	}

	return bean;
}
//AbstractAutoProxyCreator#wrapIfNecessary
//创建代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		//beanName 为空 或者 targetSourcedBeans 中有当前 bean 直接返回 
		return bean;
	} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		//Boolean.FALSE.equals(this.advisedBeans.get(cacheKey)):通过缓存判断该对象是否已经检测过 并且检测结果是不需要代理 直接返回
		return bean;
	} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
		//this.isInfrastructureClass(bean.getClass()):是否是切面类
		//this.shouldSkip(bean.getClass(), beanName):是否需要跳过
		if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
		//获得当前 Bean 所有的增强器 找到候选的增强器 并且获得能被使用的增强器。返回拍好序的增强器链
		Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
		if (specificInterceptors != DO_NOT_PROXY) {
			//增强器不为空 缓存当前 bean 增强器不为空
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 创建当前bean的代理对象 spring自动决定创建哪种 默认是用 Cglib 代理
			Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		} else {
			//缓存当前增强器为空
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
	} else {
		//缓存当前增强器为空
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
}

在获取所有的advice声明,也就是MethodIntercepter,然后通过这些拦截器创建代理对象,当后续调用方法的时候就能够实现前置处理 后置处理等等这些逻辑了。

//AbstractAutoProxyCreator#createProxy
//创建代理对象
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);
	//判断当前bean 是使用 TargetClass 代理还是接口代理
	if (!proxyFactory.isProxyTargetClass()) {
		//检查 proxyTargeClass 设置
		if (this.shouldProxyTargetClass(beanClass, beanName)) {
			//设置使用 TargetClass 而不是接口代理 
			//Cglib 代理:true
			//jdk 代理:false
			proxyFactory.setProxyTargetClass(true);
		} else {
			//代理接口
			this.evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
	//获取所有增强器
	Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
	//增强器添加到代理工厂中
	proxyFactory.addAdvisors(advisors);
	//设置被代理的类
	proxyFactory.setTargetSource(targetSource);
	//自定义代理方法 默认空实现
	this.customizeProxyFactory(proxyFactory);
	//默认false 表示代理被配置后 就不允许修改它的配置了
	proxyFactory.setFrozen(this.freezeProxy);
	if (this.advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	//获取代理对象
	return proxyFactory.getProxy(this.getProxyClassLoader());
}

责任链模式

可以看看jdk代理对象JdkDynamicAopProxy

public class ReflectiveMethodInvocation  implements MethodInvocation{
    List<MethodInterceptor> methodInterceptors;
 
    public ReflectiveMethodInvocation(List<MethodInterceptor> methodInterceptors) {
        this.methodInterceptors = methodInterceptors;
    }
 
    private int index = -1;
 
    @Override
    public Object proceed() throws Throwable {
		//如果到最后一个直接下一步
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		//获取下一个MethodMatcher  并且后移
		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;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, 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);
		}
	}
 
}

责任链这里的实现方式主要包含 methodInterceptors处理器链表 以及 自调用invoke方法,每次调用都会index++ 这样整个链表就会全部调用一遍了。
相当于我把每一个处理逻辑都看作是一个独立的处理者,然后将他们形成一个处理链,这样当一个请求进来之后,通过遍历这个处理链来处理请求。在遍历链时,通过判断,如果能处理该请求,则处理并返回,不在继续向下遍历,如果不能处理则继续向下遍历,交个下一个处理者。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值