Spring

作者: 01010100 | 来源:发表于2020-06-28 22:50 被阅读0次

    Spring初始化

    --- StandardContext --- //org.apache.catalina.core.StandardContext
    startInternal -> listenerStart -> listener.contextInitialized(ServletContextListener.contextInitialized)
    --- ContextLoaderListener ---
    contextInitialized -> initWebApplicationContext -> createWebApplicationContext(Default:XmlWebApplicationContext) -> configureAndRefreshWebApplicationContext -> refresh
    --- AbstractApplicationContext ---
    refresh
        //1.create factory and load bean definition.
        obtainFreshBeanFactory
            -> refreshBeanFactory 
            -> createBeanFactory(DefaultListableBeanFactory) 
            -> loadBeanDefinitions  //加载applicationContext文件,将里面的bean定义转成BeanDefinition,装在到BeanFactory beanDefinitionMap
        //2.invoke factory processor: Invoke factory processors registered as beans in the context.
        invokeBeanFactoryPostProcessors
            -> postProcessBeanFactory   //BeanFactoryPostProcessor,可以修改bean definitions,此动作在所有bean初始化之前 //All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans.
        //3.register bean processor: Register bean processors that intercept bean creation. 将BeanPostProcessor类型的bean提前加载、实例化初始化,并注册,然后在第4步普通bean创建时执行拦截方法:postProcessBefore/AfterInitialization
        registerBeanPostProcessors
            -> registerBeanPostProcessors
            -> getBean (for (String ppName : postProcessorNames); BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);) //go to AbstractBeanFactory.getBean getBean这里会实例化BeanPostProcessor
            -> beanFactory.addBeanPostProcessor(postProcessor);
        //4.instantiate: Instantiate all remaining (non-lazy-init) singletons. 实例化剩余普通的bean
        finishBeanFactoryInitialization(beanFactory);
            -> preInstantiateSingletons(beanFactory.preInstantiateSingletons()) //List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); for (String beanName : beanNames) -> getBean(beanName);
            -> getBean  (for (String beanName : beanNames) { getBean(beanName); })  //go to AbstractBeanFactory.getBean
    
    

    扩展

    扩展原理:
    1、init,registerBeanDefinitionParser注册BeanDefinition解释器
    2、parse:2.1.element 获取自定义的配置 2.2.registerBeanDefinition 向registry注册BeanDefinition
    registry其实就是factory:DefaultListableBeanFactory,registerBeanDefinition 注册beanDefinition,后续在finishBeanFactoryInitialization中会遍历所有beanDefinition进行实例化。
    这个注册过程其实就跟手动注解@Component一个意思,注册beanDefinition,之后由工厂进行初始化。

    --- AbstractXmlApplicationContext ---
        loadBeanDefinitions -> XmlBeanDefinitionReader.loadBeanDefinitions -> DefaultBeanDefinitionDocumentReader.registerBeanDefinitions 
        -> DefaultBeanDefinitionDocumentReader.parseBeanDefinitions -> BeanDefinitionParserDelegate.parseCustomElement
    --- BeanDefinitionParserDelegate ---
        parseCustomElement -> resolve(String namespaceUri) -> namespaceHandler.init() //NamespaceHandlerSupport -> registerBeanDefinitionParser("xx",new XXBeanDefinitionParser());
                           -> handler.parse -> XXBeanDefinitionParser.parse -> registry.registerBeanDefinition("xxBeanDefinition",xxBeanDefinition);//解析自定义的配置文件,然后一般会向registry进行注册registerBeanDefinition   
    通过NamespaceHandlerSupport、BeanDefinitionParser完成扩展:
    public class XXNamespaceHandler extends NamespaceHandlerSupport{
        @Override
        public void init() {
            registerBeanDefinitionParser("annotation-driven",new XXBeanDefinitionParser());
        }
    }
    //XXBeanDefinitionParser 也可以继承自AbstractSingleBeanDefinitionParser、AbstractBeanDefinitionParser,原理是类似的。
    public class XXBeanDefinitionParser implements BeanDefinitionParser{
        @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            //element 配置文件的对象
            RootBeanDefinition xxBeanDefinition = new RootBeanDefinition();
            BeanDefinitionRegistry registry = parserContext.getRegistry();
            registry.registerBeanDefinition("xxx", xxBeanDefinition);
            return xxBeanDefinition;
        }
    }
    

    创建Bean

    //Parse the elements at the root level in the document: "import", "alias", "bean".
    --- AbstractBeanFactory ---
        getBean
        doGetBean
        getSingleton
        createBean  //go to AbstractAutowireCapableBeanFactory.createBean
    --- AbstractAutowireCapableBeanFactory ---
        createBean 
        -> resolveBeforeInstantiation -> postProcessBeforeInstantiation (if (bean != null) -> postProcessAfterInitialization)
        -> doCreateBean 
            -> createBeanInstance -> instantiateBean -> BeanUtils.instantiateClass(constructorToUse) -> constructorToUse.newInstance(args)
            -> populateBean(postProcessAfterInstantiation -> autowire -> postProcessPropertyValues -> applyPropertyValues)
            -> initializeBean
                -> invokeAwareMethods(BeanNameAware->setBeanName, BeanClassLoaderAware->setBeanClassLoader, BeanFactoryAware->setBeanFactory)
                -> postProcessBeforeInitialization 
                -> invokeInitMethods(afterPropertiesSet&invokeCustomInitMethod) 
                -> postProcessAfterInitialization
    
    

    Bean创建关键流程如下:
    createBean
    -> postProcessBeforeInstantiation -> return null -> createBeanInstance -> postProcessAfterInstantiation -> postProcessBeforeInitialization -> invokeInitMethods -> postProcessAfterInitialization -> return bean
    -> postProcessBeforeInstantiation -> not null -> postProcessAfterInitialization -> return bean

    从这里看可以看到,在这个过程有多个可以执行拦截的地方,这些拦截也正是Spring作为一个框架的优秀之处,因为在拦截的地方可以进行各种增强,使得其拥有良好的扩展性:
    InstantiationAwareBeanPostProcessor: postProcessBeforeInstantiation/postProcessAfterInstantiation/postProcessPropertyValues 作用于实例化阶段
    BeanPostProcessor: postProcessBeforeInitialization/postProcessAfterInitialization 作用于初始化阶段

    1、createBean
    1.1 resolveBeforeInstantiation
    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);    //applyBeanPostProcessorsBeforeInstantiation
    if (bean != null) {
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);      //applyBeanPostProcessorsAfterInitialization
    }
    ...
    return bean;
    
    1.2 applyBeanPostProcessorsBeforeInstantiation
    //invoking their postProcessBeforeInstantiation methods. 调用postProcessBeforeInstantiation,这个方法在bean实例化之前执行
    //Any returned object will be used as the bean instead of actually instantiating the target bean.
    //A null return value from the post-processor will result in the target bean being instantiated.
    //若返回了非空对象,则直接被当做bean,替代后续真正实例化的bean;若返回是空的,将继续调用实际的实例化方法
    //即若在这里执行拦截返回了非空对象,后续bean的实例化将跳过,直接跳转执行bean的初始化后置操作postProcessAfterInitialization,然后直接返回
    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);    //InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
    
    return null;
    
    2、doCreateBean
    2.1 createBeanInstance(beanName, mbd, args);        //创建对象(实例化)
    2.2 populateBean(beanName, mbd, instanceWrapper);   //填充对象属性
    2.3 initializeBean                                  //初始化
    
    2.2 populateBean
    2.2.1 postProcessAfterInstantiation 
    //This is the ideal callback for performing field injection on the given bean instance. 是一个执行字段注入的回调方法。若返回false,将不再执行后续的字段注入。
    //如果返回false,将不再给bean设置属性。此接口目前三个实现都是无任何操作,仅仅只是返回了true。
    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
        continueWithPropertyPopulation = false;
        break;
    }
    if (!continueWithPropertyPopulation) {
        return;
    }
    2.2.2 autowire
    PropertyValues pvs = mbd.getPropertyValues();
    autowireByName(beanName, mbd, bw, newPvs);  //加载属性依赖的bean
    autowireByType(beanName, mbd, bw, newPvs);
    2.2.3 postProcessPropertyValues
    //Post-process the given property values before the factory applies them to the given bean. Also allows for replacing the property values to apply
    //对属性值进行后置处理,允许替换要应用的属性值
    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    if (pvs == null) {
        return;
    }
    2.2.4 applyPropertyValues
    
    2.3 initializeBean
    2.3.1 invokeAwareMethods
        private void invokeAwareMethods(final String beanName, final Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }
    2.3.2 applyBeanPostProcessorsBeforeInitialization   //postProcessBeforeInitialization
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
    2.3.3 invokeInitMethods     //afterPropertiesSet, invokeCustomInitMethod
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean...) {
            ((InitializingBean) bean).afterPropertiesSet();
        }
        invokeCustomInitMethod
    2.3.4 applyBeanPostProcessorsAfterInitialization
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
    

    AOP

    核心:AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor, InstantiationAwareBeanPostProcessor,
    BeanPostProcessor
    原理:postProcessBefore/AfterInstantiation, postProcessBefore/AfterInitialization,在Bean的创建或初始化的前后拦截,实现代理。
    核心类:AbstractAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator

    1、配置AspectJ:若需要AspactJ支持,需要添加配置,其实现对应 AnnotationAwareAspectJAutoProxyCreator,添加配置有2中方式
    1.1 配置文件文件
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    1.2 AopConfigUtils
    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary
    
    2、构建Advisor
    AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
    
    2.1 postProcessBeforeInstantiation 以这个方法为入口构建Advisor(但这里并没有做拦截)
    //AbstractAutoProxyCreator
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);
    
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {  //Advisor所在的类跳过,不执行拦截
                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.
        if (beanName != null) {
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);     //其他类执行代理创建,一般未指定targetSource,这里都不会执行代理创建
            if (targetSource != null) {
                this.targetSourcedBeans.add(beanName);
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }
    
        return null;                                                                    //未自定义TargetSource的,一般也直接返回null
    }
    
    //AspectJAwareAdvisorAutoProxyCreator
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // TODO: Consider optimization by caching the list of the aspect names
        List<Advisor> candidateAdvisors = findCandidateAdvisors();              //这里会去查找所有的Advisor,即找到所有增强方法
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor) {
                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {   //Advisor所在的类跳过,不执行拦截
                    return true;
                }
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }
    
    2.2 Advisor的构造过程
    2.2.1 查找所有bean,找出@Aspect切面的bean
    buildAspectJAdvisors - BeanFactoryAspectJAdvisorsBuilder
    for (String beanName : beanNames) {
        if (this.advisorFactory.isAspect(beanType)) {   //isAspect: hasAspectAnnotation(clazz) && !compiledByAjc(clazz)
            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
        }
    }
    
    2.2.2 找到所有的Advisor方法
    getAdvisors - ReflectiveAspectJAdvisorFactory
    for (Method method : getAdvisorMethods(aspectClass)) {
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }
    //获取所有方法,排除Pointcut注解的方法
    private List<Method> getAdvisorMethods(Class<?> aspectClass) {
        final List<Method> methods = new LinkedList<Method>();
        ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
            @Override
            public void doWith(Method method) throws IllegalArgumentException {
                // Exclude pointcuts
                if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
                    methods.add(method);
                }
            }
        });
        Collections.sort(methods, METHOD_COMPARATOR);
        return methods;
    }
    2.2.3 找到带@Around @Before等注解的方法,并将其包装成Advisor
    getAdvisor -> getPointcut -> findAspectJAnnotationOnMethod
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
            int declarationOrderInAspect, String aspectName) {
    
        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    
        AspectJExpressionPointcut expressionPointcut = getPointcut(
                candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); 
        if (expressionPointcut == null) {
            return null;
        }
    
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
    
    protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        Class<?>[] classesToLookFor = new Class<?>[] {
                Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
        for (Class<?> c : classesToLookFor) {
            AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);   //获取PointCut配置,如@Around("execution(* com.xx.xx.x..*.*(..)) || @annotation(com.xx.xx.xx.XXAnnotation)")
            if (foundAnnotation != null) {
                return foundAnnotation;
            }
        }
        return null;
    }
    
    3.3 代理的创建 postProcessAfterInitialization 
    再回顾一遍这个流程:
    refresh -> finishBeanFactoryInitialization -> preInstantiateSingletons -> getBean -> doGet.. -> createBean .. -> createBeanInstance(AbstractAutowireCapableBeanFactory) 这里就已经实例化完成,bean已经创建了 -> populateBean
    -> initializeBean -> applyBeanPostProcessorsAfterInitialization -> beanProcessor.postProcessAfterInitialization(AnnotationAwareAspectJAutoProxyCreator)
    -> postProcessAfterInitialization(AbstractAutoProxyCreator) -> wrapIfNecessary -> getAdvicesAndAdvisorsForBean(查找当前bean是否需要增强) -> AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)
    -> createProxy -> proxyFactory.getProxy -> createAopProxy(DefaultAopProxyFactory) -> getProxy (CglibAopProxy)
    
    真正代理创建并不是在postProcessBeforeInstantiation,而是postProcessAfterInitialization,所以真正拦截,将bean替换成代理对象是在postProcessAfterInitialization方法做的。
    postProcessAfterInitialization 一般的实现,如果不做代理,就直接返回bean 就可以。
    
    wrapIfNecessary
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (specificInterceptors != DO_NOT_PROXY) {
            Object proxy = createProxy;
            return proxy;   //返回的代理对象替换真正的bean
        }
        return bean;
    }
    
    DefaultAopProxyFactory
        createAopProxy:
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {   //指定了proxy-target-class=true,或hasNoUserSuppliedProxyInterfaces 即当前类没有实现接口,则使用cglib
                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);
                }
                return new ObjenesisCglibAopProxy(config);  //cglib
            }
            else {
                return new JdkDynamicAopProxy(config);      //jdk
            }
        }
    
    CglibAopProxy
        getProxy
        Enhancer enhancer = createEnhancer();
        enhancer.setSuperclass(proxySuperClass);    //targetClass
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        createProxyClassAndInstance
    

    相关文章

      网友评论

          本文标题:Spring

          本文链接:https://www.haomeiwen.com/subject/olggfktx.html