Spring AOP

1.Spring AOP的加载过程

生命周期:
1.postProcessBeforeInstantiation
2.解析注解@Aspect标识的类
3.postProcessAfterInitialization
4.找出匹配当前bean的Advisor
5.对Advisor进行排序
6.创建代理对象
7.调用代理对象
8.获取拦截器链
9.将advisor转换成MethodInterceptor
10.执行拦截器链
在这里插入图片描述

理解是:
1.扫描所有标注了@Aspect的类。放入一个cache中,并且对所有的Advisor里面的方法进行排序。
2.postProcessBeforeInstantiation判断当前类是否与切面的逻辑有关,即是否需要增强。
3.postProcessAfterInitialization 生成代理对象。
4.找到Advisor,调用等环节

通过 @Aspect 注解配置切面,通过 @EnableAspectJAutoProxy 注解开启AOP配置,引入
AspectJAutoProxyRegistrar类,最终会注册一个AnnotationAwareAspectJAutoProxyCreator类

因为AnnotationAwareAspectJAutoProxyCreator继承自BeanPostProcessor
在这里插入图片描述

postProcessBeforeInstantiation

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			// 判断当前bean是否与切面逻辑有关(Adivsor,Adivce,Pointcut实现类)
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		///获取targetSource, 如果存在则直接在对象初始化之前进行创建代理, 避免了目标对象不必要的实例化
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		//如果有自定义targetSource就要这里创建代理对象
		//这样做的好处是被代理的对象可以动态改变,而不是只针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象)
			if (beanName != null) {
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
			if (targetSource != null) {
				this.targetSourcedBeans.add(beanName);
				//获取Advisors, 这个是交给子类实现的
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}

//获取切面
@Override
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, 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) {
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

解析注解@Aspect标识的类

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

postProcessAfterInitialization

@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			//返回bean的名字或class
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
	
/**
	 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
	 * @param bean the raw bean instance
	 * @param beanName the name of the bean
	 * @param cacheKey the cache key for metadata access
	 * @return a proxy wrapping the bean, or the raw bean instance as-is
	 */
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 1.查找出和当前bean匹配的advisor
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, 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;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

找出匹配当前Bean的Advisor
在这里插入图片描述

在这里插入图片描述

创建代理对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

调用代理对象

在这里插入图片描述

获取拦截器链

将postProcessAfterInitialization排序完,可适配当前切点的Advisor 形成拦截器链进行调用?
在这里插入图片描述

将Advisor 转成MethodInterceptor
在这里插入图片描述

执行拦截器链

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值