Spring初始化过程到AOP

Posted dirac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring初始化过程到AOP相关的知识,希望对你有一定的参考价值。

初始化过程

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                // Initialize message source for this context.
                initMessageSource();
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                // Initialize other special beans in specific context subclasses.
                onRefresh();
                // Check for listener beans and register them.
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
                finishRefresh();
            }
            // ...
    }

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
-> AbstractRefreshableApplicationContext#refreshBeanFactory() get a beanFactory(DefaultListableBeanFactory)
-> loadBeanDefinitions(beanFactory)
-> AbstractXmlApplicationContext#loadBeanDefinitions, XmlBeanDefinitionReader, loadBeanDefinition...(not yet instantiate)

registerBeanPostProcessors(beanFactory)
-> 注册BPP,其中就包含AOP的BPPAbstractAutoProxyCreator,注意BPP是not-lazy-init的

finishBeanFactoryInitialization(beanFactory); 实例化非lazy-init的bean
-> DefaultListableDeanFactory#preInstantiateSingletons() -> getBean(beanName)
-> AbstractBeanFactory#getBean(beanName) -> doGetBean(name, null, null, false) -> getSingleton -> createBean
-> AbstractAutowiredCapableBeanFactory#createBean -> doCreateBean -> populateBean -> initializeBean -> applyBeanPostProcessorsBeforeInitialization -> invokeInitMethods -> applyBeanPostProcessorsAfterInitialization -> getBeanPostProcessors() 然后对每个bean挨个调用bpp的postProcessAfterInitialization方法,对于AOP,在其中就会有判定是否需要包装、是否需要生成代理等操作,最后生成一个代理(这部分就是AOP的代码了)

AOP创建代理

Spring默认会加载AbstractAutoProxyCreator这个Bean(是一个BPP)
AbstractAutoProxyCreator#postProcessAfterInitialization -> wrapIfNecessary

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return 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;
        }

        // Create proxy if we have 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;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

getAdvicesAndAdvisorsForBean方法找到所有的拦截器,调用createProxy方法生成代理。
生成Advisor[]设置到ProxyFactory中,然后调用ProxyFactory#getProxy方法获取代理(JdkDynamicAopProxy和CglibAopProxy)。其中在生成Advisors是一个表复杂的过程,涉及匹配切点、包装生成通知(AspectJPointcutAdvisor.)

ProxyFactor extends ProxyCreatorSupport extends AdvisedSupport

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

ProxyFactory以自身为参数,因为把Advisors设置进去了,生成代理时就可以拿到了。生成AopProxyCglibAopProxy或者JdkDynamicAopProxy的构造参数需要AdvisedSupport)。
对于不需要包装(拦截)的方法,有一个拦截器是ExposeInvocationInterceptor
在代理的invoke方法里,会先从AdvisedSupport中获取到拦截器链,最后包装成一个MethodInvocationReflectiveMethodInvocation)调用其proceed方法。
关键是proceed这个方法,会递归调用其中每一个interceptor,这里的this就是ReflectiveMethodInvocation,然后在interceptor的invoke方法里,有前置/后置/环绕等逻辑,或者没有逻辑(ExposeInvocationInterceptor是第一个拦截器),参数是MethodInvocation,然后再调用mi的proceed方法,回到ReflectiveMethodInvocation中继续处理,拦截器链调完之后就会反射调用返回。此处有点绕,需要多看几遍代码。

return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

拦截器接口InvocationInterceptor,前置后置等逻辑都实现了该接口。
AspectJAfterAdvice
MethodBeforeAdviceInterceptor
AspectJAroundAdvice
等等

















以上是关于Spring初始化过程到AOP的主要内容,如果未能解决你的问题,请参考以下文章

spring aop

Spring AOP之概念解释

Spring框架系列 - Spring AOP实现原理详解之AOP切面的实现

Spring

Spring Aop基础总结

这一次搞懂Spring代理创建及AOP链式调用过程