spring AOP之走马观花

在:https://www.jianshu.com/p/366c3aad046f
分析了整个IOC生成bean实例的流程,实际上,spring aop也是在IOC的基础上去实现的。
在doCreateBean()方法的后半部分,也就是initializeBean方法中,会通过BeanPostProcessor对Bean做加强:

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // 调用aware方法 如 ApplicationConetxtAward之类的
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // BeanPostProcessor前置处理
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 调用afterPropertySet等方法
            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()) {
            // BeanPostProcessor后置处理
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 这里会通过postProcessAfterInitialization 方法对bean做一定的处理
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }
 
 

这里会通过BeanPostProcessor,对bean做进一步的增强,而AOP的核心,就是一个BeanPostProcessor:


image.png

AbstractAutoProxyCreator 之 getEarlyBeanReference

在IOC中,为了解决单例模式下循环依赖的问题,spring会将实例化的bean提前暴露出来:

    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        return exposedObject;
    }

简单来说就是通过SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法获取增强后的bean,而AbstractAutoProxyCreator同样是SmartInstantiationAwareBeanPostProcessor的实现类,其中实现了getEarlyBeanReference方法:

    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        return wrapIfNecessary(bean, beanName, cacheKey);
    }

这里面会将bean放入缓存中,然后通过wrapIfNecessary对bean进行AOP包装,并将包装后的bean返回出去,wrapIfNecessary的逻辑我们后边再说。

AbstractAutoProxyCreator 之 postProcessAfterInitialization

getEarlyBeanReference是为了解决提前暴露的问题,而postProcessAfterInitialization则是AOP正常流程的入口:

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // 如果earlyProxyReferences中没有bean 则 wrapIfNecessary
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

可以看到,如果earlyProxyReferences中不含有改bean, 则remove一定会返null 从而执行wrapIfNecessary对bean进行包装。

AOP包装流程

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 关于targetSourcedBeans 先不去管它 有兴趣可以自己查下
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 不需要创建 直接返回
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //  这里shouldSkip也有加载所有advisor的作用
        // 有兴趣可以去AspectJAwareAdvisorAutoProxyCreator类看下实现
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // 上面做了一些不需要创建代理的情况的判断
        // 返回匹配当前 bean 的所有的 advisor、advice、interceptor
        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;
    }

这里会通过createProxy 方法创建代理对象:

    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 proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

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

        // 返回匹配了当前bean的Advisor
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

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

        return proxyFactory.getProxy(getProxyClassLoader());
    }

这里主要就是创建ProxyFactory并且通过proxyFactory.getProxy生成代理对象;

    public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }

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

    @Override
    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.");
            }
            // 如果要代理的类本身就是接口,则使用 JDK 动态代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // 如果有接口,会跑到这个分支
            return new JdkDynamicAopProxy(config);
        }
    }

大体上就是 实现了接口,则使用JDK动态代理,否则使用cglib动态代理。
后面两个具体实现代理就不去细说了,有兴趣的可以了解下jdk动态代理跟cglib是如何实现的。

参考:
https://www.javadoop.com/post/spring-aop-source

你可能感兴趣的:(spring AOP之走马观花)