Spring

2020-06-28  本文已影响0人  01010100

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
上一篇下一篇

猜你喜欢

热点阅读