Spring源码之AOP(三)——代理的提前生成

        代理的提前生成是在实例化的过程中,进入创建Bean的方法createBean():

        所属类:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		// 马上就要实例化Bean了,确保beanClass已被加载
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			// 实例化前
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// 实例化(主要看这个)*****
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

        在实例化前会执行resolveBeforeInstantiation(beanName, mbdToUse)方法,有可能会返回代理(而不是目标bean实例),进入resolveBeforeInstantiation():

        所属类:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			// Synthetic表示合成,如果某些Bean是合成的,则不会经过BeanPostProcessor的处理
			// hasInstantiationAwareBeanPostProcessors()方法判断spring中有无InstantiationAwareBeanPostProcessor接口类型的
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 实例化之前执行的方法
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						// 获取到实例,直接执行实例化之后的方法
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

        先执行applyBeanPostProcessorsBeforeInstantiation(),

        所属类:本类

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

        调用到AbstractAutoProxyCreator.postProcessBeforeInstantiation(),如果我们有自定义TargetSource,就在这里创建代理:

        所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

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

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			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);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			// 检查当前Bean是否有切面
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			// 创建代理
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

        在这个方法中,找切面和生成代理的代码和之前的一样,唯一不同的地方就是getCustomTargetSource(beanClass, beanName)方法,

        所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

	protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
		// We can't create fancy target sources for directly registered singletons.
		// 如果自定义的TargetSource不为空,就会调用到父类AbstractBeanFactoryBasedTargetSourceCreator的getTargetSource(beanClass, beanName)方法
		if (this.customTargetSourceCreators != null &&
				this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
			for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
				TargetSource ts = tsc.getTargetSource(beanClass, beanName);
				if (ts != null) {
					// Found a matching TargetSource.
					if (logger.isTraceEnabled()) {
						logger.trace("TargetSourceCreator [" + tsc +
								"] found custom TargetSource for bean with name '" + beanName + "'");
					}
					return ts;
				}
			}
		}

		// No custom TargetSource found.
		return null;
	}

        我们看一下this.customTargetSourceCreators,它是TargetSourceCreator的数组:

	private TargetSourceCreator[] customTargetSourceCreators;

	public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
		this.customTargetSourceCreators = targetSourceCreators;
	}

        自定义TargetSourceCreator,为了方便,通过继承AbstractBeanFactoryBasedTargetSourceCreator创建了自定义的TargetSource类:

@Component
public class CustomTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {

    @Override
    protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(Class<?> beanClass, String beanName) {
        if (getBeanFactory() instanceof ConfigurableListableBeanFactory) {
            if(beanClass.isAssignableFrom(StudentServiceImpl.class)) {
                return new CustomTargetSource();
            }
        }
        return null;
    }
}

         实现BeanPostProcessor接口,在postProcessAfterInitialization()方法中将上面自定义的TargetSourceCreator设置进去,这样,我们代理入口类的实例就会有TargetSourceCreator实例。

@Component
public class SetCustomTargetSourceCreator implements BeanPostProcessor, PriorityOrdered, BeanFactoryAware {

    private BeanFactory beanFactory;

    @Override
    public int getOrder() {
        return 45;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof AnnotationAwareAspectJAutoProxyCreator) {
            AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator = (AnnotationAwareAspectJAutoProxyCreator)bean;
            CustomTargetSourceCreator customTargetSourceCreator = new CustomTargetSourceCreator();
            customTargetSourceCreator.setBeanFactory(beanFactory);
            // 将上面自定义的TargetSourceCreator设置进去
            annotationAwareAspectJAutoProxyCreator.setCustomTargetSourceCreators(customTargetSourceCreator);
        }
        return bean;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

        自定义TargetSource类,继承AbstractBeanFactoryBasedTargetSource:

public class CustomTargetSource extends AbstractBeanFactoryBasedTargetSource {

    @Override
    public Object getTarget() {
        // getBean()实例化,在这里才会生成被代理类的实例(是目标对象,而不是代理对象)
        return getBeanFactory().getBean(getTargetBeanName());
    }
}

        AbstractBeanFactoryBasedTargetSourceCreator 作用是提前生成代理,并将目标对象变成多例,并将自定义的TargetSource类返回。

	public final TargetSource getTargetSource(Class<?> beanClass, String beanName) {
		// 创建TargetSource对象
		AbstractBeanFactoryBasedTargetSource targetSource =
				createBeanFactoryBasedTargetSource(beanClass, beanName);
		if (targetSource == null) {
			return null;
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Configuring AbstractBeanFactoryBasedTargetSource: " + targetSource);
		}

		// 生成新的BeanFactory实例
		DefaultListableBeanFactory internalBeanFactory = getInternalBeanFactoryForBean(beanName);

		// We need to override just this bean definition, as it may reference other beans
		// and we're happy to take the parent's definition for those.
		// Always use prototype scope if demanded.
		// 从之前旧的BeanFactory中取出BeanDefinition,并生成新的BeanDefinition
		BeanDefinition bd = this.beanFactory.getMergedBeanDefinition(beanName);
		GenericBeanDefinition bdCopy = new GenericBeanDefinition(bd);
		if (isPrototypeBased()) {
			// 变成原型的
			bdCopy.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		}
		// 将合并后的BeanDefinition注册到新的BeanFactory
		internalBeanFactory.registerBeanDefinition(beanName, bdCopy);

		// Complete configuring the PrototypeTargetSource.
		// 完成TargetSource的配置(TargetBeanName和BeanFactory)
		targetSource.setTargetBeanName(beanName);
		targetSource.setBeanFactory(internalBeanFactory);

		return targetSource;
	}

        回到postProcessBeforeInstantiation()方法中,得到的TargetSource就是自定义的TargetSource,然后执行createProxy()方法生成JdkDynamicAopProxy的代理实例,执行invoke()方法时调用到了自定义的CustomTargetSource类的getTarget(),在这里才生成了被代理类的实例。

        但需要注意的是,这里虽然是调用了BeanFactory.getBean()方法,后面也生成了代理,但返回的却是目标对象(原始对象),为什么?

        通过源码可以看出,把旧的传进去,生成了一个新的BeanFactory(DefaultListableBeanFactory ):

        所属类:aop.framework.autoproxy.target.AbstractBeanFactoryBasedTargetSourceCreator

	protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
		synchronized (this.internalBeanFactories) {
			DefaultListableBeanFactory internalBeanFactory = this.internalBeanFactories.get(beanName);
			if (internalBeanFactory == null) {
				internalBeanFactory = buildInternalBeanFactory(this.beanFactory);
				this.internalBeanFactories.put(beanName, internalBeanFactory);
			}
			return internalBeanFactory;
		}
	}

         接着看buildInternalBeanFactory()方法,会过滤掉支持AOP功能的入口类:AnnotationAwareAspectJAutoProxyCreator

	protected DefaultListableBeanFactory buildInternalBeanFactory(ConfigurableBeanFactory containingFactory) {
		// Set parent so that references (up container hierarchies) are correctly resolved.
		DefaultListableBeanFactory internalBeanFactory = new DefaultListableBeanFactory(containingFactory);

		// Required so that all BeanPostProcessors, Scopes, etc become available.
		internalBeanFactory.copyConfigurationFrom(containingFactory);

		// Filter out BeanPostProcessors that are part of the AOP infrastructure,
		// since those are only meant to apply to beans defined in the original factory.
		// 过滤掉支持AOP功能的BeanPostProcessor
		internalBeanFactory.getBeanPostProcessors().removeIf(beanPostProcessor ->
				beanPostProcessor instanceof AopInfrastructureBean);

		return internalBeanFactory;
	}

        我们知道,生成代理的两个条件:

  • 入口类
  • 切面

        新的BeanFactory(DefaultListableBeanFactory )中没有生成代理的入口类,所以没有生成代理,直接返回了目标类。

        要实现上面的功能需要自定义自定义TargetSource类,继承AbstractBeanFactoryBasedTargetSource,Spring为什么要这样设计呢?

        因为此时被代理实例还没进行实例化,设计成多例,多例类似于懒加载,只有用这个实例的时候才会加载:target = targetSource.getTarget();

        所属类:org.springframework.aop.framework.JdkDynamicAopProxy

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;
		// 从代理工厂中获取targetSource对象,该对象包装了被代理实例
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			// 被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;
			// 如果该属性设置为true
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				// 则把代理对象设置到ThreadLocal中
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			// 获取被代理实例
			target = targetSource.getTarget();

        如果是单例的话,就会接着进行后面的实例化;反之,如果是多例,启动的时候就不会进行后面的实例化了,直接将上面这个过程中取到的Bean返回,加快了启动速度。

        这种情况在日常业务中使用不多,如果一个类是多例,并且需要生成代理,可以采用这种方式,但是个人感觉比较鸡肋,但是原理需要理解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值