Spring AOP源码解析

AOP流程

先看这个方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

自定义初始化Bean

先有如下代码

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

// 里面是其实是执行的InstantiationAwareBeanPostProcessor的实现类AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
	return bean;
}

来看postProcessBeforeInstantiation,如果这个方法返回的不是null,将不会再执行后面的默认初始化逻辑,只会执行一下BeanPostProcessor实现类的postProcessAfterInitialization方法

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

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//advisedBeans用于存储不可代理的bean,如果包含直接返回
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			//判断当前bean是否可以被代理,然后存入advisedBeans
			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.
		//获取封装当前bean的TargetSource对象,如果不存在,则直接退出当前方法,否则从TargetSource
        // 中获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			// 获取适用于当前Bean的Advisors
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			// 生成代理类
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

Spring默认初始化Bean

在初始化阶段(此时已经给属性赋值了)

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// Bean初始化的最后阶段,执行BeanPostProcessor实现类的postProcessAfterInitialization方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

AOP的关键类是AbstractAutoProxyCreator,来看他的postProcessAfterInitialization方法

	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
		if (bean != null) {
			//缓存键:1.beanName不为空的话,使用beanName(FactoryBean会在见面加上"&")
			//2.如果beanName为空,使用Class对象作为缓存的key
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				//如果条件符合,则为bean生成代理对象
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

来看wrapIfNecessary 方法

	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//如果已经处理过(targetSourcedBeans存放已经增强过的bean)
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//advisedBeans的key为cacheKey,value为boolean类型,表示是否进行过代理
		//已经处理过的bean,不需要再次进行处理,节省时间
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//是否是内部基础设置类Class || 配置了指定bean不需要代理,如果是的话,直接缓存。
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 获取适用于当前Bean的advice
		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;
		}

		// 将这个Bean标记为已处理 
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

getAdvicesAndAdvisorsForBean和createProxy的逻辑待补充

发布了37 篇原创文章 · 获赞 1 · 访问量 1040

猜你喜欢

转载自blog.csdn.net/zhuchencn/article/details/104750950