Spring AOP源码分析(三):基于JDK动态代理和CGLIB建立代理对象的实现原理

AOP代理对象的建立spring

AOP相关的代理对象的建立主要在applyBeanPostProcessorsBeforeInstantiation方法实现:缓存

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {

        // 查找实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
        // 其中在spring-aop模块定义的AspectJAwareAdvisorAutoProxyCreator就实现了InstantiationAwareBeanPostProcessor接口
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            
            // 调用postProcessBeforeInstantiation方法建立对象result
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            
            // 若是建立成功则直接返回
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}
核心实现为:获取全部的BeanPostProcessor,而后遍历查看是否为子接口InstantiationAwareBeanPostProcessor,若是是则调用其postProcessBeforeInstantiation方法。

AOP代理对象建立器:AspectJAwareAdvisorAutoProxyCreator

InstantiationAwareBeanPostProcessor接口是BeanPostProcessor接口的子接口,主要做用以下英文所示:即主要用于为特殊定制目标bean的实例化过程,如给目标对象建立代理对象。
Typically used to suppress default instantiation for specific target beans,
for example to create proxies with special TargetSources (pooling targets,
lazily initializing targets, etc), or to implement additional injection strategies
such as field injection.

This interface is a special purpose interface, mainly for internal use within the framework
在spring-aop的配置解析的分析可知:Spring AOP源码分析(二):AOP的三种配置方式与内部解析实现
,在解析spring的XML配置文件applicationContext.xml的aop:config或aop:aspect-autoproxy标签时,会建立并注册AspectJAwareAdvisorAutoProxyCreator(aop:aspect-autoproxy对应的AnnotationAwareAspectJAutoProxyCreator为AspectJAwareAdvisorAutoProxyCreator子类)这个BeanPostProcessor到spring容器。

AspectJAwareAdvisorAutoProxyCreator的类继承体系结构中,实现了InstantiationAwareBeanPostProcessor接口,具体为在抽象父类AbstractAutoProxyCreator:同时定义了postProcessBeforeInstantiation方法的实现。
// 提供为给定的bean对象建立对应的代理对象的方法实现
// 同时提供代理对象须要的方法拦截器的建立,其中拦截器包括全部代理对象公用的拦截器和某个代理对象私有的拦截器
@SuppressWarnings("serial")
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport 
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    ...
    
    // 在bean对象实例的建立过程当中,在建立bean对象实例以前,先调用这个方法,看是否须要建立一个AOP代理对象直接返回
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);

        // 返回null,则表示不是AOP的目标对象,不须要建立代理对象
        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 = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }

            // specificInterceptors类型为Advisor[],是当前bean须要的辅助功能列表
            // 由于Advisor集成了pointcut和advice,故能够知道当前bean是否在pointcut拦截范围内,
            // 若是在获取配置对应的advice列表,该列表做为代理对象的interceptor方法拦截器
            // getAdvicesAndAdvisorsForBean由子类实现
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

            // 基于以上辅助功能列表,建立该bean对应的代理对象proxy
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());

            // 只有建立了proxy,才不返回null
            return proxy;
        }

        return null;
    }
    
    ...
    
}
postProcessBeforeInstantiation方法的核心逻辑为:经过在spring-aop配置解析时建立的advisors来为该目标bean查找对应的辅助方法advices,其中advisor为集成了pointcut和advice。这些辅助方法advices做为代理对象的方法拦截器列表specificInterceptors,即代理对象拦截目标对象的方法执行,而后在方法执行先后能够执行该方法拦截器列表对应的方法,从而为目标对象的方法添加这些辅助功能。

建立代理对象:createProxy

createProxy的定义以下:代理对象能够基于JDK的动态代理或者基于CGLIB来建立,其中默认为基于JDK的动态代理,若是aop:config的proxy-target-class属性为true或者目标类没有实现接口,则使用CGLIB来建立代理对象。
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);
    }

    // 每一个bean对象都使用一个单例的ProxyFactory来建立代理对象,由于每一个bean须要的辅助方法不同,
    // 而后将该ProxyFactory对象引用做为构造函数参数建立对应的代理对象
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    // 检查是否配置了<aop:config />节点的proxy-target-class属性为true
    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

    // 为该代理工厂添加辅助功能包装器Advisors,结合Advisors来生成代理对象的方法拦截器
    proxyFactory.addAdvisors(advisors);

    // 目标类
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    // 为目标类建立代理对象,若是配置了aop:config的proxy-target-class为true,则使用CGLIB
    // 不然若是目标类为接口则使用JDK代理,不然使用CGLIB
    return proxyFactory.getProxy(getProxyClassLoader());
}
JDK动态代理

基于接口实现,经过实现目标类所包含的接口的方法来实现代理,即返回的代理对象为接口的实现类。因为是基于JDK的动态代理实现,即实现了JDK提供的InvocationHandler接口,故在运行时在invoke方法拦截目标类对应被代理的接口的全部方法的执行:获取当前执行的方法对应的方法拦截器链,而后经过反射执行该方法时,在方法执行先后执行对应的方法拦截器。
// JDK的动态代理是基于接口的,故只能代理接口中定义的方法。
// 该类须要经过代理工厂,具体为继承了AdvisedSupport的代理工厂来建立,而不是直接建立,
// 由于AdvisedSupport提供了AOP的相关配置信息,如Advisors列表等。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    
    ...
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        try {
        
            ...
            
            Object retVal;

            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                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();
            Class<?> targetClass = (target != null ? target.getClass() : null);

            // 获取该方法对应的方法拦截器列表
            // 实现:经过该方法所在类对应的Advisors,获取该方法的辅助功能Advices列表,即方法拦截器列表。这里的实现为懒加载,
            // 即当方法第一次调用的时候才建立该方法拦截器列表,而后使用一个ConcurrentHashMap缓存起来,以后的方法调用直接使用。

            // 其中advised就是该方法的所在bean对应的ProxyFactory对象引用,经过ProxyFactory来建立AopProxy,即当前类对象实例。

            // Get the interception chain for this method.
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // Check whether we have any advice. If we don't, we can fallback on direct
            // reflective invocation of the target, and avoid creating a MethodInvocation.

            // 当前执行的方法不包括方法拦截器,即不须要额外的辅助功能,则能够直接执行
            if (chain.isEmpty()) {
                // We can skip creating a MethodInvocation: just invoke the target directly
                // Note that the final invoker must be an InvokerInterceptor so we know it does
                // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // 若是当前方法包括方法拦截器,即在执行时须要其余额外的辅助功能,则建立ReflectiveMethodInvocation
                // We need to create a method invocation...
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }

            // Massage return value if necessary.
            Class<?> returnType = method.getReturnType();
            if (retVal != null && retVal == target &&
                    returnType != Object.class && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                // Special case: it returned "this" and the return type of the method
                // is type-compatible. Note that we can't help if the target sets
                // a reference to itself in another returned object.
                retVal = proxy;
            }
            else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException(
                        "Null return value from advice does not match primitive return type for: " + method);
            }
            return retVal;
        }
        ...
    }

    ...
    
}
CGLIB代理
  • 建立目标类的子类来实现代理,代理拦截的只能是目标类的public和protected方法。核心方法为getProxy即建立代理对象,在这里织入了辅助功能。app

// 基于类的代理,具体实现为经过建立目标类的子类来实现代理,即代理对象对应的类为目标类的子类。
// 因此目标类的须要被代理的方法不能为final,由于子类没法重写final的方法;同时被代理的方法须要是public或者protected,不能是static,private或者包可见,即不加可见修饰符。
// 如在事务中,@Transactional注解不能对private,static,final,包可见的方法添加事务功能,只能为public方法。
// 这个代理对象也须要经过代理工厂来建立,具体为继承了AdvisedSupport的代理工厂来建立,而不是直接建立。
@SuppressWarnings("serial")
class CglibAopProxy implements AopProxy, Serializable {
    
    ...
    
    // 建立代理对象
    public Object getProxy(@Nullable ClassLoader classLoader) {
            
            ...
            
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

            Class<?> proxySuperClass = rootClass;
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                for (Class<?> additionalInterface : additionalInterfaces) {
                    this.advised.addInterface(additionalInterface);
                }
            }

            // Validate the class, writing log messages as necessary.
            validateClassIfNecessary(proxySuperClass, classLoader);

            // 建立目标类的子类来实现代理,即织入辅助功能
            // Configure CGLIB Enhancer...
            Enhancer enhancer = createEnhancer();
            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);
                if (classLoader instanceof SmartClassLoader &&
                        ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

            Callback[] callbacks = getCallbacks(rootClass);
            Class<?>[] types = new Class<?>[callbacks.length];
            for (int x = 0; x < types.length; x++) {
                types[x] = callbacks[x].getClass();
            }
            // fixedInterceptorMap only populated at this point, after getCallbacks call above
            enhancer.setCallbackFilter(new ProxyCallbackFilter(
                    this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);

            // 建立代理对象
            // Generate the proxy class and create a proxy instance.
            return createProxyClassAndInstance(enhancer, callbacks);
        }
        
        ...
        
    }
    
    ...
    
}

获取更多学习资料,能够加群:473984645或扫描下方二维码ide

 

相关文章
相关标签/搜索