Spring

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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342