Spring AOP的底层实现分析

在之前的通过Spring AOP实现自定义注解一文中,使用切面的方式来对注解方法实现了AOP增强,下面从底层分析一下Spring框架是如何生成AOP代理对象的。

在使用@Aspect注解时,由于beanPostProcessors中包含了AnnotationAwareAspectJAutoProxyCreator,所以对于所有的bean在初始化的时候都会检查是否进行aop代理。在Spring框架中,postProcessAfterInitialization方法用于对所有的已经初始化完成的bean进行二次处理。

AbstractAutoProxyCreator.java

    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // 检查缓存中是否存在这个bean,如果不存在则进行bean的增强处理,否则直接返回bean
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

wrapIfNecessary()方法用于判断当前的bean是否需要进行AOP代理

AbstractAutoProxyCreator.java

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 如果之前曾经检查过这个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;
        }

        // 从所有的advisor中进行检索,判断是否有合适的advisor可以进行代理
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 如果发现有合适的advisor可以进行代理则生成代理对象
        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不需要进行代理,并直接返回bean
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

创造代理对象时使用createProxy()方法

AbstractAutoProxyCreator.java

    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);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        // 在这里为bean设置增强的切面
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        // 首先设置需要被注入的advisor
        proxyFactory.addAdvisors(advisors);
        // 接着设置被代理的对象
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        // 通过工厂方法获取代理对象
        return proxyFactory.getProxy(getProxyClassLoader());
    }

proxyFactory的getProxy()方法调用了ProxyCreatorSupport的AopProxy()方法

ProxyCreatorSupport.java

    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

在实际的DefaultAopProxyFactory中重写了ProxyCreatorSupport的createAopProxy方法,并最终在这里生成了代理对象,代理对象的生成有两种策略,一种是cglib,一种是jdk动态代理

DefaultAopProxyFactory.java

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            // 如果设置了强制使用cglib代理或者是没有接口则使用cglib
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // 否则使用jdk提供的动态代理
            return new JdkDynamicAopProxy(config);
        }
    }

在上一步返回两个不同的对象后,都会使用getProxy()方法生成真正的代理对象并最为bean放入bean容器中,两种代理对象的不同就体现在这两种不同的getProxy()方法实现,其中cglib使用Enhancer来生成代理对象,jdk使用Proxy来生成。

cglib

    public Object getProxy(@Nullable ClassLoader classLoader) {
        ...

        try {
            ...

            // 使用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);

            // 在这里构建真正的代理对象
            return createProxyClassAndInstance(enhancer, callbacks);
        }
        catch (CodeGenerationException | IllegalArgumentException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                    ": Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }
        catch (Throwable ex) {
            // TargetSource.getTarget() failed
            throw new AopConfigException("Unexpected AOP exception", ex);
        }
    }

jdk动态代理

    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        // 调用Proxy生成代理对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

猜你喜欢

转载自blog.csdn.net/turbo_zone/article/details/84638053