绥化二手房网:【(学习)底层原理系列】重读spring<源码>1-建立基本的认知模『型』

admin 6个月前 (05-08) 科技 42 1
【JAVa并发工具类】JaVa并发容器

开篇闲扯

工作 中[,【相很多人都有这种体会】,‘与其修改别人代码’,《宁愿自己重写》。

为什么?

先说为什么愿意自己写:

「从」0-1【的过程】, 是建[立在自己已有认知基础上,去用自己熟悉的方式构建一件作品。也就是说,

1.“对目标的认”知是熟悉的(当然每个人水平可能不一样,也有可能是错的,“这不重要”,重要的是自认为是符合的);

2.<使用的工具是自己熟悉的>。

接下来就是去做一件自己熟悉的领域的事而已。

(再说为什么不愿意修改别人代)码:

1.首先要在阅读代码过程 中[,去不断的检视对方的实现是否符合自己的认知,很可能由于双方认识程度不同,导致一开始对目标的认识就不一致。

2.『实现方式是自己不熟悉的』,【要不断的去适应对方】的风格,要不断的去猜测对方的用意,还要记忆大量的内容

3.『人都有趋利避害的心里』,对于自己不熟悉的东西进行阅读,是有读错的风险的,如果再修改,那风险就更大了。对这种风险的规避,是来自骨子里的。

在猿界[,‘阅读源码的经验是’非常被看重的

你很多人工作了很多年,却总是不能沉下心来读一读

【这】里扯了这么多,算是一种让自己心安的解释吧

<下面开始正文>,尝试换一种风格来解析Spring源码。因为看了网上很多人写的文章,{就是粘了一堆代码},简单的做了解释,{个人认为这并不具有可操作}性,“与其这样看只言片语的代码”,还不如直接看源码来的完整。

&NBsp;Spring临门一脚

我们知,spring的两大核心功能是IOC〖《《和》》〗AOP。{其 中[}IOC解决了我们用的实例的创建 问题[,AOP解决的是对方法的扩展 问题[。不管是出于什么考虑,「初衷」都是为了减少代码编写,减少在非业务开发之外的精力。

〖【今天我们先来学习】〗IOC:

「依」赖注入,『或者叫控制反转』。不熟悉的可以自行查一下,(<无非概念而已>)。

Java『是面向』对象的语言,在没有Spring<之前>,甚至于现在我们在开发过程 中[,需要用到某对象了,『我们是这么来』做的:

MyObject obj=new MyObject();
...

obj.methodName();

...  

于是你会发现,到处都充斥着这种实例初始化的代码,可能在类变量里,《也可能在方法的局部变量里》。于是有人就想了,我能不能把这些变量统一管理起来呢?比如统一放在类变量里, 【可以在当前类实例化时在】[构造方法里统一实例化,{也可以在声明时就实例化}。比如这样:

public class MySuperClass1{
  MySubClasSa subA=new MySubClassA(); 
  MySubClassB subB=new MySubClassB(); 
  MySuperClass2 super2=new MySuperClass2();
  ...
public void super1Methord(){
   super2.super2Methord(this.subA);
 } 
}

 

(嗯),看起来「【好】」了很多,这样在MySuperClass1{类 中[},【无论有多少‘个方法’用到了那两个】sub【类的实例】,都不用再自己实例化了。

你还用拼音为变量命名?新人OIer『别傻了』,“教你写出优质代码”

那么 问题[来了,〖如果需要〗在方法super1Methord() 中[调用另一个类MySuperClass2的方法super2Methord()【(如代码所示)】,而这‘个方法’也用到了MySubClassA的实例,怎么办?聪明的你肯定想到了,把对象作为参数传递进去,就如代码 中[一样。

那么 问题[又来了,(假如《在第》三个类)MySuperClass3 中[,存在着〖《《和》》〗MySuperClass1<一样的情况>,那么该怎么办呢?是不是还要自己创建对象,然后传递进去?这样不就是重复创建吗?那怎么办才能更「【好】」一些呢?

可能你会想到,我弄一个根类,所有类都继承自这个类,在这个根类里实例化「【好】」所有对象,然后就不用重复创建了。

是的,思路是对的,‘只是’,『这就需要自己来维护这些类』,‘如果新增了’,就要时刻记得去根{类 中[}{添加}一下,如果不需要了,要记得去根{类 中[}删除下,项目小还「【好】」,项目大了,(谁还记得哪个有用哪个没用)?<最后这个根类>,【就谁都不敢轻】易改。那有没有什么「【好】」的方式可以解决呢?〖比如我配置下〗,或者加个注解,『这个根类就能自动识别我新加的类』, 就能给自动[ 的实例化[?

springIOC,就做了这件事。 它提供了容器[,【也就是我们说的根类】,“我们”在使用的时候,就可以通过名字或其他方式,「从」容器 中[拿到事先创建「【好】」的实例对象。

APPlicatI.NContext ctx = new ClassPathXmlApplicationContext("aop-test.xml");

ITestBean testBean = (ITestBean) ((ClassPathXmlApplicationContext) ctx).getBean("testBean");

String str = testBean.getStr();

{对应到源码里},容器就是各种xxxApplicationContext,例如上面代码 中[的ClassPathXmlApplicationContext。

我觉得以上是一定要理解清晰的知[识点。<知道了>what,再带着疑问〖《《和》》〗目标去了解How,会事半功倍。

<下面开始分析源码>,在分析源码过程 中[,我会「从」繁杂的代码 中[把主流程梳理出来,尝试去掉细枝末节,尽量保证思路的连贯性。

ApplicationContext ctx = new ClassPathXmlApplicationContext("aop-test.xml");

这就是初始化容器,<我们跟进去>,发现在其构造函数 中[,『有一个核心方法是需要我们关注的』:refresh()

public ClassPathXmlApplicationContext(String[] confIGLocatioNS, boolean refresh, ApplicationContext pARent)
            throws BeanSException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

为什么这里叫刷新呢?{不是应该叫}创建、〖构造之类的吗〗?

在接口注释里有一句话

As this is a startup method, it should destroy alreADy created singletons

作为一个启动方法,它需要销毁已创建的单例。

(销毁后然后再创建)。这不就是刷新的意思吗。

继续跟进去:

refresh()方法里,最核心的12‘个方法’,共同支撑起Spring的架子

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1 《刷新前的预处理》:
            prepareRefresh();

            // 2 【创建bean】生成BeanFactory,并加载beanDefinition
            ConfigurableListableBeanFactory beanFactory = obtAInFreshBeanFactory();

            // 3 对BeanFactory进行预处理:
            prepareBeanFactory(beanFactory);

            try {
                //4 空实现,暂时《忽略》
                postProCESsBeanFactory(beanFactory);

                // 5 【{‘扩展点’}】{添加}BeanFactory的后置处理器BeanFactoryPostProcessor并执行之。「用于在」bean实例化<之前>,读取beanDefinition并『进行修改』。
                invokeBeanFactoryPostProcessors(beanFactory);

                // 6 【{‘扩展点’}】:{添加}BeanPostProcessor,注意区别于上述的BeanFactoryPostProcessor,这里‘只是’{添加},《在第》11步 中[,bean实例化时执行初始化方法<之前>后,可对bean『进行修改』
                registerBeanPostProcessors(beanFactory);

                // 7 初始化MessageSource 组件[,{做国际化功能}:「消息」<绑定>,「消息」解析
                initMessageSource();

                // 8 【事件『监听』】初始化事件处理器
                initApplicatIZ*ONEventMulticaster();

                // 9 在这里是空实现
                onRefresh();

                // 10 【事件『监听』】注册『监听』器,就是实现了ApplicationListener接口的bean,〖《《和》》〗「上面的」8‘搭配使用’
                registerListeners();

                // 11 【创建bean】〖初始〗化非懒加载的单例bean,两个作用
          // .真正 的实例化[bean
          // .实现Aop,创建代理bean
finishBeanFactoryInitialization(beanFactory); // 12 【事件『监听』】完成context的刷新,发布ContextRefereshedEvent事件 finishRefresh(); } catch (BeansException ex)// 《忽略》 } finally { // 《忽略》 } } }

{其实归纳下},『需要重点关注的就分为以下三类』:

1.【创建bean】:2〖《《和》》〗11

2.【{‘扩展点’}】:处理器注册〖《《和》》〗执行,包括BeanFactoryPostProcessor〖《《和》》〗BeanPostProcessor:4,5,6,11

3.【事件『监听』】:8,10,12

「【好】」,(『第一篇就先建立』)基本的印象。

 

,

sunbet

Sunbet www.0379st.com《信誉来自于每一位客》户的口碑,Sunbet<贴心的服务>,『让你尊享贵宾通』道,秒速提现,秒速到账,同行业 中[体验最佳。

Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:绥化二手房网:【(学习)底层原理系列】重读spring<源码>1-建立基本的认知模『型』

网友评论

  • (*)

最新评论

  • 做皇冠足球代理 2020-05-08 02:12:32 回复

    sunbet 申博:www.ipvps.cn是亚洲最有公信力的网上娱乐平台,拉斯维加斯官方网址。Sunbet提供2018年最新最全的多种在线娱乐方式,可满足不同类型的客户,为广大会员提供一个最满意的平台。语文学渣羡慕了

    1

站点信息

  • 文章总数:950
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1967
  • 评论总数:52
  • 浏览总数:5308